dcbnl.c revision 3a9a231d977222eea36eae091df2c358e03ac839
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}, 1813e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { 1843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, 1853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1863e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 187ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid/* DCB number of traffic classes nested attributes. */ 188ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { 189ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, 190ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, 191ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, 192ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, 193ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid}; 194ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic LIST_HEAD(dcb_app_list); 1969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic DEFINE_SPINLOCK(dcb_lock); 1979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* standard netlink reply call */ 1992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 2002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 seq, u16 flags) 2012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); 2122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = cmd; 2162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_pad = 0; 2172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, attr, value); 2192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* end the message, assign the nlmsg_len. */ 2232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 2242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 2252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2267eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend return -EINVAL; 2272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 2302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 231858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 2322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB, 2452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags); 2462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, 2512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_PFC_GCFG; 2802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 2952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 2982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 3002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 3012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, nest); 3022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3077eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 3112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 312858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, 3182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 3192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 3202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 3212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 3222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 3232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 3242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 3252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 3272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 3282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 3312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 3322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 3342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 3362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 3372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_GPERM_HWADDR; 3382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 3402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), 3422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck perm_addr); 3432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3487eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 353858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 35846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckstatic int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, 35946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u32 pid, u32 seq, u16 flags) 36046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 36146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct sk_buff *dcbnl_skb; 36246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlmsghdr *nlh; 36346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct dcbmsg *dcb; 36446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 36546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 36646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int ret = -EINVAL; 36746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 36846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 36946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) 37146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return ret; 37246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 37446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 37546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 37646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 37746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 37946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!dcbnl_skb) 38046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 38146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 38346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb = NLMSG_DATA(nlh); 38546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->dcb_family = AF_UNSPEC; 38646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->cmd = DCB_CMD_GCAP; 38746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); 38946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 39046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 39146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 39346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 39446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 39646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 39746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 39846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 40046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 40146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 40246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 40346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 40446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 40546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_end(dcbnl_skb, nest); 40946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 41146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 41346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 4147eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 41546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 41746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duycknlmsg_failure: 41846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr: 419858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 42046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr_out: 42146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return -EINVAL; 42246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 42346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 42433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, 42533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 42633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 42733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct sk_buff *dcbnl_skb; 42833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlmsghdr *nlh; 42933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct dcbmsg *dcb; 43033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 43133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 43233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 43333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 43433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 43533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) 43733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 43833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 44033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 44133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 44233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 44433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 44533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 44733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!dcbnl_skb) { 44833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 45033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 45333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb = NLMSG_DATA(nlh); 45533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->dcb_family = AF_UNSPEC; 45633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->cmd = DCB_CMD_GNUMTCS; 45733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); 45933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!nest) { 46033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 46133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 46233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 46333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 46533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 46633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 46833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 46933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 47033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 47233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 47333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 47433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 47633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 47733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 47833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 47933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } else { 48133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 48233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_end(dcbnl_skb, nest); 48533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 48733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 48933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 49033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 4917eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 49233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 49333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 49533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duycknlmsg_failure: 49633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 497858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 49833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr_out: 49933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 50033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 50133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, 50333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 50433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 50533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 50633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 50733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 50833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 50933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5108b124a8e14c04378466ddfe63e41fc5035f957ebDon Skidmore if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) 51133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 51233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 51433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 51533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 51733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 51833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 51933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 52033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 52233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 52333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 52433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 52633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 52833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 53033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto operr; 53133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 53233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckoperr: 53433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS, 53533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck DCB_ATTR_NUMTCS, pid, seq, flags); 53633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 53833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 53933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 54033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5410eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, 5420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5440eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5450eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5460eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 5470eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5480eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5490eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, 5500eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, 5510eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5520eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5530eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5540eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5550eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5560eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, 5570eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5580eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5590eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5600eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 5610eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5620eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) 5630eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5640eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5650eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 5660eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5670eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 5680eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5690eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, 5700eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5710eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5720eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5730eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5740eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 575579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, 576579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 577579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 578579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct sk_buff *dcbnl_skb; 579579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlmsghdr *nlh; 580579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct dcbmsg *dcb; 581579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 582579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 583579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 584579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 585579496865cf4ea429146382d62047ffdbaab0deeYi Zou int ret = -EINVAL; 586579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5873dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (!tb[DCB_ATTR_APP]) 588579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 589579496865cf4ea429146382d62047ffdbaab0deeYi Zou 590579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 591579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 592579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 593579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 594579496865cf4ea429146382d62047ffdbaab0deeYi Zou 595579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 596579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 597579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 598579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 599579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 600579496865cf4ea429146382d62047ffdbaab0deeYi Zou 601579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 602579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 603579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 604579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 605579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 606579496865cf4ea429146382d62047ffdbaab0deeYi Zou 607579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 6083dce38a02d6370dca690cd923619d4b00024b723John Fastabend 6093dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (netdev->dcbnl_ops->getapp) { 6103dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 6113dce38a02d6370dca690cd923619d4b00024b723John Fastabend } else { 6123dce38a02d6370dca690cd923619d4b00024b723John Fastabend struct dcb_app app = { 6133dce38a02d6370dca690cd923619d4b00024b723John Fastabend .selector = idtype, 6143dce38a02d6370dca690cd923619d4b00024b723John Fastabend .protocol = id, 6153dce38a02d6370dca690cd923619d4b00024b723John Fastabend }; 6163dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = dcb_getapp(netdev, &app); 6173dce38a02d6370dca690cd923619d4b00024b723John Fastabend } 618579496865cf4ea429146382d62047ffdbaab0deeYi Zou 619579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* send this back */ 620579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 621579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!dcbnl_skb) 622579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 623579496865cf4ea429146382d62047ffdbaab0deeYi Zou 624579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 625579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb = NLMSG_DATA(nlh); 626579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->dcb_family = AF_UNSPEC; 627579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->cmd = DCB_CMD_GAPP; 628579496865cf4ea429146382d62047ffdbaab0deeYi Zou 629579496865cf4ea429146382d62047ffdbaab0deeYi Zou app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); 630d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl if (!app_nest) 631d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl goto out_cancel; 632d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl 633579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); 634579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 635579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 636579496865cf4ea429146382d62047ffdbaab0deeYi Zou 637579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); 638579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 639579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 640579496865cf4ea429146382d62047ffdbaab0deeYi Zou 641579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); 642579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 643579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 644579496865cf4ea429146382d62047ffdbaab0deeYi Zou 645579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_end(dcbnl_skb, app_nest); 646579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlmsg_end(dcbnl_skb, nlh); 647579496865cf4ea429146382d62047ffdbaab0deeYi Zou 648579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 649579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 650579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto nlmsg_failure; 651579496865cf4ea429146382d62047ffdbaab0deeYi Zou 652579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 653579496865cf4ea429146382d62047ffdbaab0deeYi Zou 654579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 655579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_cancel(dcbnl_skb, app_nest); 656579496865cf4ea429146382d62047ffdbaab0deeYi Zounlmsg_failure: 657579496865cf4ea429146382d62047ffdbaab0deeYi Zou kfree_skb(dcbnl_skb); 658579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 659579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 660579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 661579496865cf4ea429146382d62047ffdbaab0deeYi Zou 662579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 663579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 664579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 6659ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend int err, ret = -EINVAL; 666579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 667579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 668579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 669579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6709ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!tb[DCB_ATTR_APP]) 671579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 672579496865cf4ea429146382d62047ffdbaab0deeYi Zou 673579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 674579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 675579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 676579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 677579496865cf4ea429146382d62047ffdbaab0deeYi Zou 678579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 679579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 680579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 681579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 682579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 683579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 684579496865cf4ea429146382d62047ffdbaab0deeYi Zou 685579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 686579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 687579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 688579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 689579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 690579496865cf4ea429146382d62047ffdbaab0deeYi Zou 691579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 692579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 693579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (netdev->dcbnl_ops->setapp) { 6959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 6969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } else { 6979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app app; 6989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.selector = idtype; 6999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.protocol = id; 7009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.priority = up; 7019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = dcb_setapp(netdev, &app); 7029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 7039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 7049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 7059ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend pid, seq, flags); 706579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 707579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 708579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 709579496865cf4ea429146382d62047ffdbaab0deeYi Zou 7102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, 7112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 7122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 7142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 7152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 7162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 7182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 7192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 7202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 7222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgtx || 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 7272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 7282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 7292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 7302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 7322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 7332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG; 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 7502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 7532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 7562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 7602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 7612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 7622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 7632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 7642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_nest = nla_nest_start(dcbnl_skb, i); 7682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 7692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 7722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 7732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 7742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 7772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 7822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 7832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 7842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 7962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 8052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, param_nest); 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, tc_pct); 8402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, pg_nest); 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 8502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8517eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, param_nest); 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 8582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, pg_nest); 8592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 8602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 861858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 8622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 8632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 8642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, 8682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); 8712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, 8742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); 8772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, 8802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 8842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) 8862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 8892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8901486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), 8911486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE, 8922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 8932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, 8982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 9012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 9042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) 9062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 9092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 9102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 9112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 9152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 9162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 9182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 9192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 9202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, 9232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 9242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 9252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, 9292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) 9342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, 9372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); 9382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, 9432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 9442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 9462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 9472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 9502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 9512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 9522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 9532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 9552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgtx || 9562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 9572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 9582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 9592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 9622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 9632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 9672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 9682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 9712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 9722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 9762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 9772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 9782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 9792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 9812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 9822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 9832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 9852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 9862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 9882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 9892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 9912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 9922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 9932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 9952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 9962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 9972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 9982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 9992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 10002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 10032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 10042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 10052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 10092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 10102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 10112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 10132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 10152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 10162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 10172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 10182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 10222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, 10272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 10282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_ATTR_PG_CFG, pid, seq, flags); 10292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 10312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 10322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, 10352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); 10382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, 10412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); 10442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1046859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, 1047859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1048859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1049859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct sk_buff *dcbnl_skb; 1050859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlmsghdr *nlh; 1051859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct dcbmsg *dcb; 1052859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 1053859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 1054859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1055859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 1056859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1057859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 1058859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1059859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1060859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || 1061859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 1062859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1063859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1064859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 1065859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 1066859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1067859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1068859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1069859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1070859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1071859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!dcbnl_skb) 1072859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1073859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1074859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1075859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1076859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb = NLMSG_DATA(nlh); 1077859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->dcb_family = AF_UNSPEC; 1078859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->cmd = DCB_CMD_BCN_GCFG; 1079859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1080859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); 1081859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 1082859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1083859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1084859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 1085859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 1086859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1087859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1088859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1089859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1090859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1091859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 1092859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 1093859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value_byte); 1094859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1095859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1096859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1097859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1098f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1099859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1100859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1101859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1102859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 1103859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 1104859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u32(dcbnl_skb, i, value_integer); 1105859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1106859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1107859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1108859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1109859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_end(dcbnl_skb, bcn_nest); 1110859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1111859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 1112859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1113859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 1114859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 11157eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 1116859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1117859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 1118859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1119859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 1120859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_cancel(dcbnl_skb, bcn_nest); 1121859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duycknlmsg_failure: 1122859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1123858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 1124859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_out: 1125859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = -EINVAL; 1126859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1127859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1128859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1129859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, 1130859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1131859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1132859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 1133859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1134859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1135859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1136859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 1137859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1138f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || 1139f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 1140859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1141859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 1143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 1144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 1145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1150859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1151859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 1152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 1153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 1154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1156f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 1160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 1161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 1162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, 1165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck pid, seq, flags); 1166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1168859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1169859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1170dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 1171dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_nested_type, int app_info_type, 1172dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_entry_type) 1173eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid{ 1174eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_peer_app_info info; 1175eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_app *table = NULL; 1176eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1177eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 app_count; 1178eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid int err; 1179eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1180eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1181eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1182eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * retrieve the peer app configuration form the driver. If the driver 1183eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * handlers fail exit without doing anything 1184eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1185eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getappinfo(netdev, &info, &app_count); 1186eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err && app_count) { 1187eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); 1188eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!table) 1189eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return -ENOMEM; 1190eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1191eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getapptable(netdev, table); 1192eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1193eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1194eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) { 1195eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 i; 1196eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct nlattr *app; 1197eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1198eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1199eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * build the message, from here on the only possible failure 1200eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * is due to the skb size 1201eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1202eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = -EMSGSIZE; 1203eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1204dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid app = nla_nest_start(skb, app_nested_type); 1205eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!app) 1206eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1207eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1208dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (app_info_type) 1209dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, app_info_type, sizeof(info), &info); 1210dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1211eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid for (i = 0; i < app_count; i++) 1212dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app), 1213eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid &table[i]); 1214eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1215eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid nla_nest_end(skb, app); 1216eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1217eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = 0; 1218eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1219eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravidnla_put_failure: 1220eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid kfree(table); 1221eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return err; 1222eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid} 12233e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12243e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz GET commands. */ 1225314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) 12263e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 12279ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct nlattr *ieee, *app; 12289ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 12293e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1230c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend int dcbx; 1231314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err = -EMSGSIZE; 12323e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12333e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); 12343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12353e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 12363e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ieee) 12373e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto nla_put_failure; 12383e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12393e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getets) { 12403e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets ets; 12413e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getets(netdev, &ets); 12423e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!err) 12433e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets); 12443e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12453e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12463e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getpfc) { 12473e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc pfc; 12483e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getpfc(netdev, &pfc); 12493e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!err) 12503e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc); 12513e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12523e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12539ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 12549ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!app) 12559ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto nla_put_failure; 12569ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 12579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 12589ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 1259e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 126070bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), 126170bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter &itr->app); 126270bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (err) { 126370bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter spin_unlock(&dcb_lock); 126470bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter goto nla_put_failure; 126570bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 126670bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 12679ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1268c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 1269c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (netdev->dcbnl_ops->getdcbx) 1270c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = netdev->dcbnl_ops->getdcbx(netdev); 1271c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend else 1272c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = -EOPNOTSUPP; 1273c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 12749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 12759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend nla_nest_end(skb, app); 12769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1277eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /* get peer info if available */ 1278eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getets) { 1279eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_ets ets; 1280eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getets(netdev, &ets); 1281eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) 1282eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets); 1283eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1284eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1285eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getpfc) { 1286eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_pfc pfc; 1287eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getpfc(netdev, &pfc); 1288eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) 1289eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc); 1290eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1291eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1292eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1293dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1294dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_PEER_APP, 1295dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP_UNSPEC, 1296dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP); 1297eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (err) 1298eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1299eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1300eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 13013e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_nest_end(skb, ieee); 1302c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (dcbx >= 0) { 1303c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 1304c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (err) 1305c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend goto nla_put_failure; 1306c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend } 13073e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1308314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return 0; 1309314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13103e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendnla_put_failure: 1311314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 13123e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 13133e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, 13155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dir) 13165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 pgid, up_map, prio, tc_pct; 13185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 13195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG; 13205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pg = nla_nest_start(skb, i); 13215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pg) 13235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 13265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *tc_nest = nla_nest_start(skb, i); 13275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!tc_nest) 13295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid pgid = DCB_ATTR_VALUE_UNDEFINED; 13325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid prio = DCB_ATTR_VALUE_UNDEFINED; 13335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 13345b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid up_map = DCB_ATTR_VALUE_UNDEFINED; 13355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 13375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0, 13385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 13395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0, 13415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 13425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_PGID, pgid); 13445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 13455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 13465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct); 13475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, tc_nest); 13485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 13515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 13525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 13545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0, 13555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 13565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, 13585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 13595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, i, tc_pct); 13605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pg); 13625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 13635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 13655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return -EMSGSIZE; 13665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) 13695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *cee, *app; 13715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct dcb_app_type *itr; 13725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 13735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dcbx, i, err = -EMSGSIZE; 13745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 value; 13755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); 13775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid cee = nla_nest_start(skb, DCB_ATTR_CEE); 13795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!cee) 13805b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pg */ 13835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) { 13845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 1); 13855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) { 13905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 0); 13915b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pfc */ 13965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpfccfg) { 13975b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC); 13985b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13995b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pfc_nest) 14005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 14035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); 14045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, i, value); 14055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pfc_nest); 14075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local app */ 14105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_lock(&dcb_lock); 14115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); 14125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app) 141340f5d72a4fc098c47068e3888cfb055922f6519fDan Carpenter goto dcb_unlock; 14145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid list_for_each_entry(itr, &dcb_app_list, list) { 1416e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 14175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *app_nest = nla_nest_start(skb, 14185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_APP); 14195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app_nest) 14205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, 14235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.selector); 14245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u16(skb, DCB_APP_ATTR_ID, 14285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.protocol); 14295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, 14335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.priority); 14345b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app_nest); 14385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app); 14415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (netdev->dcbnl_ops->getdcbx) 14435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = netdev->dcbnl_ops->getdcbx(netdev); 14445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 14455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = -EOPNOTSUPP; 14465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 14485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* features flags */ 14505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getfeatcfg) { 14515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT); 14525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!feat) 14535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX; 14565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid i++) 14575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!ops->getfeatcfg(netdev, i, &value)) 14585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT_U8(skb, i, value); 14595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, feat); 14615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* peer info if available */ 14645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpg) { 14655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pg pg; 14665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpg(netdev, &pg); 14675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!err) 14685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg); 14695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpfc) { 14725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pfc pfc; 14735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpfc(netdev, &pfc); 14745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!err) 14755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc); 14765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 14795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 14805b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_TABLE, 14815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_INFO, 14825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP); 14835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, cee); 14875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* DCBX state */ 14895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx >= 0) { 14905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 14915b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 14955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Raviddcb_unlock: 14975b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 14985b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 14995b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return err; 15005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_notify(struct net_device *dev, int event, int cmd, 15035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid, int dcbx_ver) 1504314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1505314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(dev); 1506314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1507314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1508314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcbmsg *dcb; 1509314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 1510314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1511314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1512314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1513314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1514314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1515314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1516314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1517314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1518314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1519314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlh = nlmsg_put(skb, pid, 0, event, sizeof(*dcb), 0); 1520314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nlh == NULL) { 15214d054f2f1445aceedab3f9642692d55d2caa7ec6Dan Carpenter nlmsg_free(skb); 1522314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EMSGSIZE; 1523314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1524314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1525314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb = NLMSG_DATA(nlh); 1526314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->dcb_family = AF_UNSPEC; 1527314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->cmd = cmd; 1528314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 15295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) 15305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_ieee_fill(skb, dev); 15315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 15325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, dev); 15335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 1534314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1535314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* Report error to broadcast listeners */ 1536314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_cancel(skb, nlh); 1537314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend kfree_skb(skb); 1538314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_set_sk_err(net, RTNLGRP_DCB, err); 1539314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1540314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* End nlmsg and notify broadcast listeners */ 1541314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1542314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL); 1543314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1544314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1545314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1546314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 15475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, 15495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 15505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 15515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_IEEE); 15525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15535b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_ieee_notify); 15545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_cee_notify(struct net_device *dev, int event, int cmd, 15565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 15575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 15585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_CEE); 15595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15605b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_cee_notify); 1561314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1562314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not 1563314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * be completed the entire msg is aborted and error value is returned. 1564314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * No attempt is made to reconcile the case where only part of the 1565314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * cmd can be completed. 1566314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend */ 1567314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, 1568314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend u32 pid, u32 seq, u16 flags) 1569314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1570314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1571314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1572314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err = -EOPNOTSUPP; 1573314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1574314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1575314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1576314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 15774003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend if (!tb[DCB_ATTR_IEEE]) 15784003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend return -EINVAL; 15794003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend 1580314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1581314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1582314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1583314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1584314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1585314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { 1586314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); 1587314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setets(netdev, ets); 1588314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1589314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1590314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1591314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1592314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { 1593314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); 1594314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setpfc(netdev, pfc); 1595314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1596314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1597314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1598314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1599314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1600314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *attr; 1601314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int rem; 1602314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1603314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1604314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcb_app *app_data; 1605314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1606314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend continue; 1607314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend app_data = nla_data(attr); 1608314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ops->ieee_setapp) 1609314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setapp(netdev, app_data); 1610314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend else 1611b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = dcb_ieee_setapp(netdev, app_data); 1612314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1613314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1614314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1615314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1616314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1617314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabenderr: 1618314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, 1619314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend pid, seq, flags); 16205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); 1621314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1622314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1623314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1624314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, 1625314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend u32 pid, u32 seq, u16 flags) 1626314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1627314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(netdev); 1628314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1629314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1630314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcbmsg *dcb; 1631314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1632314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1633314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1634314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1635314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1636314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1637314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1638314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1639314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1640314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1641314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1642314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nlh == NULL) { 16434d054f2f1445aceedab3f9642692d55d2caa7ec6Dan Carpenter nlmsg_free(skb); 1644314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EMSGSIZE; 1645314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1646314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1647314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb = NLMSG_DATA(nlh); 1648314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->dcb_family = AF_UNSPEC; 1649314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->cmd = DCB_CMD_IEEE_GET; 1650314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1651314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = dcbnl_ieee_fill(skb, netdev); 1652314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1653314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1654314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_cancel(skb, nlh); 1655314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend kfree_skb(skb); 1656314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1657314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1658314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = rtnl_unicast(skb, net, pid); 1659314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1660314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1661314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1662314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1663f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1664f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendstatic int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, 1665f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend u32 pid, u32 seq, u16 flags) 1666f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1667f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1668f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1669f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -EOPNOTSUPP; 1670f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1671f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!ops) 1672f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EOPNOTSUPP; 1673f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1674f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!tb[DCB_ATTR_IEEE]) 1675f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EINVAL; 1676f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1677f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1678f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1679f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1680f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1681f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1682f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1683f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *attr; 1684f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int rem; 1685f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1686f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1687f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app *app_data; 1688f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1689f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1690f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend continue; 1691f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend app_data = nla_data(attr); 1692f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ops->ieee_delapp) 1693f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = ops->ieee_delapp(netdev, app_data); 1694f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend else 1695f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = dcb_ieee_delapp(netdev, app_data); 1696f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1697f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto err; 1698f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1699f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1700f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1701f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabenderr: 1702f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE, 1703f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend pid, seq, flags); 17045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); 1705f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1706f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1707f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1708f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 17096241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid/* DCBX configuration */ 17106241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, 17116241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 17126241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 17137f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 17146241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17156241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid if (!netdev->dcbnl_ops->getdcbx) 17167f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17176241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17186241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, 17196241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); 17206241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17216241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 17226241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 17236241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17246241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, 17256241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 17266241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 17277f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 17286241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u8 value; 17296241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17307f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setdcbx) 17317f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17327f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 17337f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_DCBX]) 17347f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 17356241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17366241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid value = nla_get_u8(tb[DCB_ATTR_DCBX]); 17376241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17386241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), 17396241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, 17406241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid pid, seq, flags); 17416241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17426241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 17436241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 17446241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 1745ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, 1746ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1747ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1748ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct sk_buff *dcbnl_skb; 1749ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlmsghdr *nlh; 1750ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct dcbmsg *dcb; 1751ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1752ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 17537f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1754ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid int getall = 0; 1755ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 17567f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->getfeatcfg) 17577f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17587f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 17597f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 17607f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1761ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1762ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1763ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 17647f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1765ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1766ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1767ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1768ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!dcbnl_skb) { 17697f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -ENOBUFS; 1770ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1771ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1772ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1773ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1774ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1775ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb = NLMSG_DATA(nlh); 1776ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->dcb_family = AF_UNSPEC; 1777ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->cmd = DCB_CMD_GFEATCFG; 1778ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1779ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); 1780ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!nest) { 17817f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -EMSGSIZE; 17827f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 1783ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1784ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1785ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[DCB_FEATCFG_ATTR_ALL]) 1786ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid getall = 1; 1787ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1788ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1789ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!getall && !data[i]) 1790ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1791ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1792ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 17937f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!ret) 1794ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_put_u8(dcbnl_skb, i, value); 1795ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 17967f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) { 17977f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nla_nest_cancel(dcbnl_skb, nest); 17987f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 17997f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid } 1800ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1801ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nla_nest_end(dcbnl_skb, nest); 1802ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1803ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlmsg_end(dcbnl_skb, nlh); 1804ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18057f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return rtnl_unicast(dcbnl_skb, &init_net, pid); 18067f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravidnla_put_failure: 18077f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nlmsg_cancel(dcbnl_skb, nlh); 1808ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidnlmsg_failure: 1809ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid kfree_skb(dcbnl_skb); 1810ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr_out: 1811ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1812ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1813ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1814ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, 1815ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1816ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1817ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 18187f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1819ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 1820ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18217f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setfeatcfg) 18227f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -ENOTSUPP; 18237f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 18247f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 18257f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1826ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1827ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1828ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 1829ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18307f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1831ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err; 1832ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1833ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1834ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[i] == NULL) 1835ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1836ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1837ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid value = nla_get_u8(data[i]); 1838ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1839ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); 1840ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1841ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (ret) 18427f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto err; 1843ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1844ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr: 18457f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, 18467f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid pid, seq, flags); 18477f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 1848ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1849ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1850ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1851dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid/* Handle CEE DCBX GET commands. */ 1852dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1853dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid u32 pid, u32 seq, u16 flags) 1854dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid{ 18555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct net *net = dev_net(netdev); 1856dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct sk_buff *skb; 1857dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct nlmsghdr *nlh; 1858dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct dcbmsg *dcb; 1859dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 18605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int err; 1861dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1862dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!ops) 1863dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -EOPNOTSUPP; 1864dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1865dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1866dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!skb) 1867dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -ENOBUFS; 1868dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 18695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 18705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (nlh == NULL) { 18715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_free(skb); 18725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return -EMSGSIZE; 18735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 1874dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1875dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb = NLMSG_DATA(nlh); 1876dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->dcb_family = AF_UNSPEC; 1877dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->cmd = DCB_CMD_CEE_GET; 1878dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 18795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, netdev); 188037cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid 18815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err < 0) { 18825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_cancel(skb, nlh); 18835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_free(skb); 18845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } else { 18855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_end(skb, nlh); 18865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = rtnl_unicast(skb, net, pid); 188737cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid } 188837cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid return err; 1889dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid} 1890dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 18912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 18922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 18932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 18942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 18952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); 18962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 18972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid = skb ? NETLINK_CB(skb).pid : 0; 18982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 18992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 190009ad9bc752519cc167d0a573e1acf69b5c707c67Octavian Purdila if (!net_eq(net, &init_net)) 19012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 19042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 19052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 19062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 19072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 19092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 19122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 19132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops) 19162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 19172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck switch (dcb->cmd) { 19192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GSTATE: 19202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, 19212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_GCFG: 19242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 19252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GPERM_HWADDR: 19282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, 19292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_GCFG: 19322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 19332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_GCFG: 19362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 19372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 1939859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_GCFG: 1940859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 1941859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1942859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 19432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SSTATE: 19442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, 19452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_SCFG: 19482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 19492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SET_ALL: 19532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, 19542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_SCFG: 19572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 19582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_SCFG: 19612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 19622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 196446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck case DCB_CMD_GCAP: 196546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, 196646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh->nlmsg_flags); 196746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto out; 196833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_GNUMTCS: 196933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 197033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 197133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 197233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_SNUMTCS: 197333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 197433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 197533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 19760eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_GSTATE: 19770eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 19780eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 19790eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 19800eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_SSTATE: 19810eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 19820eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 19830eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 1984859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_SCFG: 1985859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 1986859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1987859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 1988579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_GAPP: 1989579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, 1990579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1991579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 1992579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_SAPP: 1993579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1994579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1995579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 19963e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_SET: 19973e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, 1998f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 19993e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 20003e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_GET: 20013e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, 2002f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 2003f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto out; 2004f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend case DCB_CMD_IEEE_DEL: 2005f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq, 2006f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 20073e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 20086241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_GDCBX: 20096241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, 20106241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 20116241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 20126241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_SDCBX: 20136241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, 20146241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 20156241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 2016ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_GFEATCFG: 2017ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 2018ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 2019ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 2020ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_SFEATCFG: 2021ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 2022ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 2023ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 2024dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid case DCB_CMD_CEE_GET: 2025dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, 2026dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlh->nlmsg_flags); 2027dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid goto out; 20282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck default: 20292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 20302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 20312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerrout: 20322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 20332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 20342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 20352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 20362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 20372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 20389ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 20399ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * dcb_getapp - retrieve the DCBX application user priority 20409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 20419ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * On success returns a non-zero 802.1p user priority bitmap 20429ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * otherwise returns 0 as the invalid user priority bitmap to 20439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * indicate an error. 20449ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 20459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_getapp(struct net_device *dev, struct dcb_app *app) 20469ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 20479ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 20489ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend u8 prio = 0; 20499ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20509ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 20519ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 20529ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == app->selector && 20539ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == app->protocol && 2054e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 20559ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend prio = itr->app.priority; 20569ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend break; 20579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20589ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20599ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 20609ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20619ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return prio; 20629ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 20639ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_getapp); 20649ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20659ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 2066b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_setapp - add CEE dcb application data to app list 20679ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 2068b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * Priority 0 is an invalid priority in CEE spec. This routine 2069b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * removes applications from the app list if the priority is 2070b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * set to zero. 20719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 2072ab6baf980b095c70a56c5eb2f58166aef8a0edc8John Fastabendint dcb_setapp(struct net_device *dev, struct dcb_app *new) 20739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 20749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 20757ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend struct dcb_app_type event; 20767ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend 2077e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 20787ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.app, new, sizeof(event.app)); 20796bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 20806bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 20819ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20829ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 20839ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* Search for existing match and replace */ 20849ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 20859ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == new->selector && 20869ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == new->protocol && 2087e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 20889ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) 20899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.priority = new->priority; 20909ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend else { 20919ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&itr->list); 20929ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(itr); 20939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto out; 20959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* App type does not exist add new application type */ 20989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) { 20999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *entry; 21009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); 21019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!entry) { 21029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 21039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return -ENOMEM; 21049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21059ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 21069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend memcpy(&entry->app, new, sizeof(*new)); 2107e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad entry->ifindex = dev->ifindex; 21089ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_add(&entry->list, &dcb_app_list); 21099ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21109ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendout: 21119ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 21127ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 21139ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return 0; 21149ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 21159ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_setapp); 21169ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 2117b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend/** 2118a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority 2119a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * 2120a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * Helper routine which on success returns a non-zero 802.1Qaz user 2121a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * priority bitmap otherwise returns 0 to indicate the dcb_app was 2122a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * not found in APP list. 2123a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend */ 2124a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabendu8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) 2125a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend{ 2126a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend struct dcb_app_type *itr; 2127a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend u8 prio = 0; 2128a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2129a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_lock(&dcb_lock); 2130a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2131a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend if (itr->app.selector == app->selector && 2132a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend itr->app.protocol == app->protocol && 2133e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2134a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend prio |= 1 << itr->app.priority; 2135a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend } 2136a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend } 2137a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_unlock(&dcb_lock); 2138a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2139a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend return prio; 2140a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend} 2141a364c8cf80251849bab207be8c9e66253c8ca8f8John FastabendEXPORT_SYMBOL(dcb_ieee_getapp_mask); 2142a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2143a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend/** 2144b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_ieee_setapp - add IEEE dcb application data to app list 2145b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * 2146b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * This adds Application data to the list. Multiple application 2147b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * entries may exists for the same selector and protocol as long 2148b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * as the priorities are different. 2149b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend */ 2150b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendint dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) 2151b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend{ 2152b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type *itr, *entry; 2153b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type event; 2154b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend int err = 0; 2155b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2156e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 2157b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&event.app, new, sizeof(event.app)); 21586bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 21596bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 2160b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2161b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_lock(&dcb_lock); 2162b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* Search for existing match and abort if found */ 2163b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2164b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (itr->app.selector == new->selector && 2165b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend itr->app.protocol == new->protocol && 2166b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend itr->app.priority == new->priority && 2167e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2168b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = -EEXIST; 2169b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend goto out; 2170b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2171b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2172b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2173b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* App entry does not exist add new entry */ 2174b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); 2175b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!entry) { 2176b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = -ENOMEM; 2177b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend goto out; 2178b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2179b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2180b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&entry->app, new, sizeof(*new)); 2181e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad entry->ifindex = dev->ifindex; 2182b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend list_add(&entry->list, &dcb_app_list); 2183b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendout: 2184b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_unlock(&dcb_lock); 2185b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!err) 2186b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 2187b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend return err; 2188b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend} 2189b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John FastabendEXPORT_SYMBOL(dcb_ieee_setapp); 2190b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2191f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend/** 2192f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * dcb_ieee_delapp - delete IEEE dcb application data from list 2193f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * 2194f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * This removes a matching APP data from the APP list 2195f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend */ 2196f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendint dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) 2197f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 2198f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type *itr; 2199f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type event; 2200f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -ENOENT; 2201f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2202e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 2203f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend memcpy(&event.app, del, sizeof(event.app)); 22046bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 22056bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 2206f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2207f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_lock(&dcb_lock); 2208f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend /* Search for existing match and remove it. */ 2209f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2210f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (itr->app.selector == del->selector && 2211f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend itr->app.protocol == del->protocol && 2212f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend itr->app.priority == del->priority && 2213e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2214f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend list_del(&itr->list); 2215f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend kfree(itr); 2216f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = 0; 2217f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto out; 2218f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 2219f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 2220f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2221f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendout: 2222f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_unlock(&dcb_lock); 2223f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!err) 2224f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 2225f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 2226f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 2227f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John FastabendEXPORT_SYMBOL(dcb_ieee_delapp); 2228f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 22297c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6Shmulik Ravidstatic void dcb_flushapp(void) 22309ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 22319ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *app; 22322a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter struct dcb_app_type *tmp; 22339ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 22349ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 22352a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { 22369ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&app->list); 22379ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(app); 22389ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 22399ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 22409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 22419ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 22422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 22432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 22449ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend INIT_LIST_HEAD(&dcb_app_list); 22459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 2246c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); 2247c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); 22482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 22492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 22502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 22512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 22522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 22532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 22542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 22552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 22562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 22579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend dcb_flushapp(); 22582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 22592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 2260