dcbnl.c revision dc6ed1df5a5f84e45e77e2acb6fd99b995414956
12f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* 22f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Copyright (c) 2008, 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> 282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/sock.h> 292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/** 312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Data Center Bridging (DCB) is a collection of Ethernet enhancements 322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * intended to allow network traffic with differing requirements 332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * (highly reliable, no drops vs. best effort vs. low latency) to operate 342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * and co-exist on Ethernet. Current DCB features are: 352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a 372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * framework for assigning bandwidth guarantees to traffic classes. 382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Priority-based Flow Control (PFC) - provides a flow control mechanism which 402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can work independently for each 802.1p priority. 412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Congestion Notification - provides a mechanism for end-to-end congestion 432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * control for protocols which do not have built-in congestion management. 442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * More information about the emerging standards for these Ethernet features 462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can be found at: http://www.ieee802.org/1/pages/dcbridges.html 472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This file implements an rtnetlink interface to allow configuration of DCB 492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * features for capable devices. 502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck */ 512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_AUTHOR("Lucy Liu, <lucy.liu@intel.com>"); 537a6b6f515f77d1c62a2f383b6dce18cb0af0cf4fJeff KirsherMODULE_DESCRIPTION("Data Center Bridging netlink interface"); 542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_LICENSE("GPL"); 552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/**************** DCB attribute policies *************************************/ 572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB netlink attributes policy */ 59b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { 60859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, 61859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_STATE] = {.type = NLA_U8}, 62859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, 63859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED}, 64859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, 652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, 66859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_CAP] = {.type = NLA_NESTED}, 67859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 68859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 696fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_ATTR_APP] = {.type = NLA_NESTED}, 703e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, 716241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_ATTR_DCBX] = {.type = NLA_U8}, 72ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_ATTR_FEATCFG] = {.type = NLA_NESTED}, 732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority flow control to User Priority nested attributes */ 76b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { 772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, 782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, 792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, 802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_3] = {.type = NLA_U8}, 812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_4] = {.type = NLA_U8}, 822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_5] = {.type = NLA_U8}, 832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_6] = {.type = NLA_U8}, 842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_7] = {.type = NLA_U8}, 852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG}, 862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority grouping nested attributes */ 89b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { 902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, 912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, 922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, 932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_3] = {.type = NLA_NESTED}, 942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_4] = {.type = NLA_NESTED}, 952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_5] = {.type = NLA_NESTED}, 962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_6] = {.type = NLA_NESTED}, 972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_7] = {.type = NLA_NESTED}, 982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_ALL] = {.type = NLA_NESTED}, 992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_0] = {.type = NLA_U8}, 1002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_1] = {.type = NLA_U8}, 1012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_2] = {.type = NLA_U8}, 1022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_3] = {.type = NLA_U8}, 1032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_4] = {.type = NLA_U8}, 1042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_5] = {.type = NLA_U8}, 1052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_6] = {.type = NLA_U8}, 1062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_7] = {.type = NLA_U8}, 1072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_ALL] = {.type = NLA_FLAG}, 1082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB traffic class nested attributes. */ 111b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { 1122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, 1132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, 1142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, 1152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_BW_PCT] = {.type = NLA_U8}, 1162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG}, 1172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck/* DCB capabilities nested attributes. */ 120b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { 12146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, 12246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, 12346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, 12446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8}, 12546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8}, 12646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, 12746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, 12846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, 1296241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_CAP_ATTR_DCBX] = {.type = NLA_U8}, 13046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck}; 1312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 13233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck/* DCB capabilities nested attributes. */ 133b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { 13433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, 13533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, 13633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, 13733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck}; 13833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 139859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck/* DCB BCN nested attributes. */ 140b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { 141859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, 142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, 143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, 144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_3] = {.type = NLA_U8}, 145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_4] = {.type = NLA_U8}, 146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_5] = {.type = NLA_U8}, 147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_6] = {.type = NLA_U8}, 148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_7] = {.type = NLA_U8}, 149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG}, 150f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32}, 151f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_1] = {.type = NLA_U32}, 152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALPHA] = {.type = NLA_U32}, 153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_BETA] = {.type = NLA_U32}, 154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GD] = {.type = NLA_U32}, 155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GI] = {.type = NLA_U32}, 156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TMAX] = {.type = NLA_U32}, 157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TD] = {.type = NLA_U32}, 158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RMIN] = {.type = NLA_U32}, 159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_W] = {.type = NLA_U32}, 160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RD] = {.type = NLA_U32}, 161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RU] = {.type = NLA_U32}, 162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_WRTT] = {.type = NLA_U32}, 163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RI] = {.type = NLA_U32}, 164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_C] = {.type = NLA_U32}, 165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG}, 166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck}; 167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1686fa382af61338908e5713234bcee598423f661c3Yi Zou/* DCB APP nested attributes. */ 169b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { 1706fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, 1716fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_ID] = {.type = NLA_U16}, 1726fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 1736fa382af61338908e5713234bcee598423f661c3Yi Zou}; 1746fa382af61338908e5713234bcee598423f661c3Yi Zou 1753e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* IEEE 802.1Qaz nested attributes. */ 1763e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { 1773e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, 1783e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, 1793e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, 1803e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1813e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { 1833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, 1843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 186ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid/* DCB number of traffic classes nested attributes. */ 187ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { 188ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, 189ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, 190ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, 191ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, 192ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid}; 193ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic LIST_HEAD(dcb_app_list); 1959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic DEFINE_SPINLOCK(dcb_lock); 1969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* standard netlink reply call */ 1982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 1992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 seq, u16 flags) 2002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); 2112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = cmd; 2152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_pad = 0; 2162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, attr, value); 2182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* end the message, assign the nlmsg_len. */ 2222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 2232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 2242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2257eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend return -EINVAL; 2262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 230858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 2312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, 2352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB, 2442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags); 2452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, 2502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 2752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_PFC_GCFG; 2792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 2942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 2972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 3002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, nest); 3012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3067eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 3102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 311858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, 3172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 3182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 3192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 3202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 3212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 3222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 3232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 3242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 3262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 3272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 3302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 3312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 3332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 3352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 3362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_GPERM_HWADDR; 3372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 3392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), 3412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck perm_addr); 3422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3477eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 352858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 35746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckstatic int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, 35846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u32 pid, u32 seq, u16 flags) 35946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 36046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct sk_buff *dcbnl_skb; 36146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlmsghdr *nlh; 36246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct dcbmsg *dcb; 36346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 36446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 36546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int ret = -EINVAL; 36646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 36746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 36846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 36946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) 37046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return ret; 37146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 37346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 37446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 37546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 37646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 37846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!dcbnl_skb) 37946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 38046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 38246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb = NLMSG_DATA(nlh); 38446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->dcb_family = AF_UNSPEC; 38546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->cmd = DCB_CMD_GCAP; 38646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); 38846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 38946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 39046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 39246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 39346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 39546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 39646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 39746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 39946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 40046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 40146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 40246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 40346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 40446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_end(dcbnl_skb, nest); 40846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 40946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 41046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 41246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 4137eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 41446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 41646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duycknlmsg_failure: 41746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr: 418858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 41946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr_out: 42046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return -EINVAL; 42146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 42246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 42333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, 42433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 42533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 42633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct sk_buff *dcbnl_skb; 42733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlmsghdr *nlh; 42833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct dcbmsg *dcb; 42933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 43033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 43133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 43233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 43333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 43433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) 43633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 43733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 43933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 44033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 44133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 44333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 44433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 44633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!dcbnl_skb) { 44733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 44933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 45233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb = NLMSG_DATA(nlh); 45433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->dcb_family = AF_UNSPEC; 45533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->cmd = DCB_CMD_GNUMTCS; 45633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); 45833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!nest) { 45933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 46033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 46133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 46233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 46433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 46533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 46733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 46833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 46933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 47133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 47233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 47333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 47533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 47633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 47733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 47833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 47933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } else { 48033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 48133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_end(dcbnl_skb, nest); 48433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 48633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 48833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 48933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 4907eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 49133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 49233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 49433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duycknlmsg_failure: 49533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 496858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 49733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr_out: 49833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 49933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 50033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, 50233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 50333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 50433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 50533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 50633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 50733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 50833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5098b124a8e14c04378466ddfe63e41fc5035f957ebDon Skidmore if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) 51033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 51133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 51333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 51433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 51633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 51733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 51833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 51933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 52133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 52233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 52333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 52533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 52733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 52933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto operr; 53033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 53133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckoperr: 53333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS, 53433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck DCB_ATTR_NUMTCS, pid, seq, flags); 53533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 53733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 53833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 53933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5400eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, 5410eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5440eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5450eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 5460eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5470eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5480eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, 5490eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, 5500eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5510eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5520eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5530eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5540eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5550eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, 5560eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5570eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5580eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5590eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 5600eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5610eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) 5620eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5630eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5640eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 5650eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5660eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 5670eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5680eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, 5690eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5700eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5710eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5720eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5730eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 574579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, 575579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 576579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 577579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct sk_buff *dcbnl_skb; 578579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlmsghdr *nlh; 579579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct dcbmsg *dcb; 580579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 581579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 582579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 583579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 584579496865cf4ea429146382d62047ffdbaab0deeYi Zou int ret = -EINVAL; 585579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5863dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (!tb[DCB_ATTR_APP]) 587579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 588579496865cf4ea429146382d62047ffdbaab0deeYi Zou 589579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 590579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 591579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 592579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 593579496865cf4ea429146382d62047ffdbaab0deeYi Zou 594579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 595579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 596579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 597579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 598579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 599579496865cf4ea429146382d62047ffdbaab0deeYi Zou 600579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 601579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 602579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 603579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 604579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 605579496865cf4ea429146382d62047ffdbaab0deeYi Zou 606579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 6073dce38a02d6370dca690cd923619d4b00024b723John Fastabend 6083dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (netdev->dcbnl_ops->getapp) { 6093dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 6103dce38a02d6370dca690cd923619d4b00024b723John Fastabend } else { 6113dce38a02d6370dca690cd923619d4b00024b723John Fastabend struct dcb_app app = { 6123dce38a02d6370dca690cd923619d4b00024b723John Fastabend .selector = idtype, 6133dce38a02d6370dca690cd923619d4b00024b723John Fastabend .protocol = id, 6143dce38a02d6370dca690cd923619d4b00024b723John Fastabend }; 6153dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = dcb_getapp(netdev, &app); 6163dce38a02d6370dca690cd923619d4b00024b723John Fastabend } 617579496865cf4ea429146382d62047ffdbaab0deeYi Zou 618579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* send this back */ 619579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 620579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!dcbnl_skb) 621579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 622579496865cf4ea429146382d62047ffdbaab0deeYi Zou 623579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 624579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb = NLMSG_DATA(nlh); 625579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->dcb_family = AF_UNSPEC; 626579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->cmd = DCB_CMD_GAPP; 627579496865cf4ea429146382d62047ffdbaab0deeYi Zou 628579496865cf4ea429146382d62047ffdbaab0deeYi Zou app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); 629d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl if (!app_nest) 630d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl goto out_cancel; 631d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl 632579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); 633579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 634579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 635579496865cf4ea429146382d62047ffdbaab0deeYi Zou 636579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); 637579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 638579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 639579496865cf4ea429146382d62047ffdbaab0deeYi Zou 640579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); 641579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 642579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 643579496865cf4ea429146382d62047ffdbaab0deeYi Zou 644579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_end(dcbnl_skb, app_nest); 645579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlmsg_end(dcbnl_skb, nlh); 646579496865cf4ea429146382d62047ffdbaab0deeYi Zou 647579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 648579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 649579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto nlmsg_failure; 650579496865cf4ea429146382d62047ffdbaab0deeYi Zou 651579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 652579496865cf4ea429146382d62047ffdbaab0deeYi Zou 653579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 654579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_cancel(dcbnl_skb, app_nest); 655579496865cf4ea429146382d62047ffdbaab0deeYi Zounlmsg_failure: 656579496865cf4ea429146382d62047ffdbaab0deeYi Zou kfree_skb(dcbnl_skb); 657579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 658579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 659579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 660579496865cf4ea429146382d62047ffdbaab0deeYi Zou 661579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 662579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 663579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 6649ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend int err, ret = -EINVAL; 665579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 666579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 667579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 668579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6699ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!tb[DCB_ATTR_APP]) 670579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 671579496865cf4ea429146382d62047ffdbaab0deeYi Zou 672579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 673579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 674579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 675579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 676579496865cf4ea429146382d62047ffdbaab0deeYi Zou 677579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 678579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 679579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 680579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 681579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 682579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 683579496865cf4ea429146382d62047ffdbaab0deeYi Zou 684579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 685579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 686579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 687579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 688579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 689579496865cf4ea429146382d62047ffdbaab0deeYi Zou 690579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 691579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 692579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (netdev->dcbnl_ops->setapp) { 6949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 6959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } else { 6969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app app; 6979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.selector = idtype; 6989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.protocol = id; 6999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.priority = up; 7009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = dcb_setapp(netdev, &app); 7019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 7029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 7039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 7049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend pid, seq, flags); 705579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 706579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 707579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 708579496865cf4ea429146382d62047ffdbaab0deeYi Zou 7092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, 7102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 7112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 7132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 7142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 7152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 7162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 7182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 7192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 7202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 7242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgtx || 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 7272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 7282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 7292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 7312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 7322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG; 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); 7472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 7552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 7592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 7602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 7612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 7622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 7632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_nest = nla_nest_start(dcbnl_skb, i); 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 7682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 7712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 7722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 7732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 7742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 7772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 7812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 7822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 7832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 7882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 7912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 8022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 8052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, 8112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, param_nest); 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, tc_pct); 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, pg_nest); 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8507eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 8512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 8532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 8552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, param_nest); 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, pg_nest); 8582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 8592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 860858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 8612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 8622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 8632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, 8672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); 8702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, 8732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); 8762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, 8792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 8832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) 8852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 8882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8891486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), 8901486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE, 8912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 8922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, 8972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 9002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 9032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) 9052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 9082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 9092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 9102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 9142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 9152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 9172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 9182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 9192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, 9222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 9232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 9242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, 9282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) 9332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, 9362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); 9372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, 9422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 9432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 9452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 9462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 9492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 9502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 9512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 9522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 9542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgtx || 9552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 9562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 9572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 9582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 9612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 9622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 9662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 9672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 9702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 9712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 9752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 9762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 9772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 9782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 9802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 9812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 9822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 9842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 9852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 9872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 9882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 9902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 9912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 9922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 9942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 9952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 9962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 9972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 9982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 9992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 10022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 10032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 10042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 10082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 10092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 10102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 10122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 10142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 10152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 10162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 10172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 10212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, 10262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 10272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_ATTR_PG_CFG, pid, seq, flags); 10282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 10302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 10312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, 10342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); 10372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, 10402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); 10432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1045859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, 1046859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1047859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1048859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct sk_buff *dcbnl_skb; 1049859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlmsghdr *nlh; 1050859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct dcbmsg *dcb; 1051859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 1052859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 1053859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1054859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 1055859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1056859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 1057859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1058859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1059859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || 1060859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 1061859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1062859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1063859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 1064859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 1065859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1066859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1067859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1068859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1069859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1070859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!dcbnl_skb) 1071859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1072859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1073859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1074859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1075859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb = NLMSG_DATA(nlh); 1076859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->dcb_family = AF_UNSPEC; 1077859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->cmd = DCB_CMD_BCN_GCFG; 1078859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1079859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); 1080859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 1081859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1082859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1083859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 1084859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 1085859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1086859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1087859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1088859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1089859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1090859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 1091859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 1092859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value_byte); 1093859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1094859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1095859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1096859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1097f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1098859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1099859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1100859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1101859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 1102859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 1103859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u32(dcbnl_skb, i, value_integer); 1104859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1105859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1106859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1107859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1108859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_end(dcbnl_skb, bcn_nest); 1109859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1110859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 1111859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1112859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 1113859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 11147eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 1115859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1116859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 1117859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1118859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 1119859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_cancel(dcbnl_skb, bcn_nest); 1120859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duycknlmsg_failure: 1121859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1122858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 1123859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_out: 1124859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = -EINVAL; 1125859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1126859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1127859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1128859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, 1129859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1130859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1131859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 1132859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1133859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1134859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1135859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 1136859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1137f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || 1138f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 1139859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1140859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1141859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 1142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 1143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 1144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1150859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 1151859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 1152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 1153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1155f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 1159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 1160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 1161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, 1164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck pid, seq, flags); 1165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1168859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 11693e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not 11703e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend * be completed the entire msg is aborted and error value is returned. 11713e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend * No attempt is made to reconcile the case where only part of the 11723e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend * cmd can be completed. 11733e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend */ 11743e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, 11753e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend u32 pid, u32 seq, u16 flags) 11763e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 11773e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 11783e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 11793e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend int err = -EOPNOTSUPP; 11803e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11813e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ops) 11823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto err; 11833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 11853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 11863e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (err) 11873e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto err; 11883e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11893e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { 11903e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); 11913e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_setets(netdev, ets); 11923e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (err) 11933e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto err; 11943e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 11953e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11963e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) { 11973e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); 11983e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_setpfc(netdev, pfc); 11993e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (err) 12003e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto err; 12013e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12023e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 12043e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct nlattr *attr; 12053e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend int rem; 12063e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12073e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 12083e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct dcb_app *app_data; 12093e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 12103e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend continue; 12113e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend app_data = nla_data(attr); 12129ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (ops->ieee_setapp) 12139ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = ops->ieee_setapp(netdev, app_data); 12149ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend else 12159ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = dcb_setapp(netdev, app_data); 12163e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (err) 12173e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto err; 12183e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12193e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12203e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12213e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabenderr: 12223e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, 12233e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend pid, seq, flags); 12243e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend return err; 12253e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 12263e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1227dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 1228dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_nested_type, int app_info_type, 1229dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_entry_type) 1230eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid{ 1231eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_peer_app_info info; 1232eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_app *table = NULL; 1233eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1234eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 app_count; 1235eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid int err; 1236eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1237eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1238eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1239eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * retrieve the peer app configuration form the driver. If the driver 1240eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * handlers fail exit without doing anything 1241eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1242eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getappinfo(netdev, &info, &app_count); 1243eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err && app_count) { 1244eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); 1245eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!table) 1246eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return -ENOMEM; 1247eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1248eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getapptable(netdev, table); 1249eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1250eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1251eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) { 1252eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 i; 1253eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct nlattr *app; 1254eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1255eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1256eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * build the message, from here on the only possible failure 1257eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * is due to the skb size 1258eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1259eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = -EMSGSIZE; 1260eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1261dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid app = nla_nest_start(skb, app_nested_type); 1262eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!app) 1263eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1264eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1265dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (app_info_type) 1266dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, app_info_type, sizeof(info), &info); 1267dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1268eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid for (i = 0; i < app_count; i++) 1269dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app), 1270eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid &table[i]); 1271eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1272eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid nla_nest_end(skb, app); 1273eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1274eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = 0; 1275eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1276eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravidnla_put_failure: 1277eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid kfree(table); 1278eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return err; 1279eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid} 12803e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12813e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz GET commands. */ 12823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, 12833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend u32 pid, u32 seq, u16 flags) 12843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 12853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct sk_buff *skb; 12863e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct nlmsghdr *nlh; 12873e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct dcbmsg *dcb; 12889ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct nlattr *ieee, *app; 12899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 12903e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 12913e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend int err; 12923e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12933e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ops) 12943e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend return -EOPNOTSUPP; 12953e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12963e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 12973e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!skb) 12983e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend return -ENOBUFS; 12993e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13003e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 13013e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13023e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend dcb = NLMSG_DATA(nlh); 13033e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend dcb->dcb_family = AF_UNSPEC; 13043e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend dcb->cmd = DCB_CMD_IEEE_GET; 13053e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13063e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); 13073e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13083e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 13093e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ieee) 13103e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto nla_put_failure; 13113e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13123e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getets) { 13133e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets ets; 13143e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getets(netdev, &ets); 13153e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!err) 13163e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets); 13173e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 13183e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13193e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getpfc) { 13203e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc pfc; 13213e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getpfc(netdev, &pfc); 13223e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!err) 13233e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc); 13243e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 13253e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13269ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 13279ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!app) 13289ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto nla_put_failure; 13299ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 13309ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 13319ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 133270bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0) { 133370bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), 133470bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter &itr->app); 133570bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (err) { 133670bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter spin_unlock(&dcb_lock); 133770bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter goto nla_put_failure; 133870bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 133970bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 13409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 13419ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 13429ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend nla_nest_end(skb, app); 13439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1344eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /* get peer info if available */ 1345eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getets) { 1346eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_ets ets; 1347eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getets(netdev, &ets); 1348eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) 1349eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets); 1350eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1351eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1352eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getpfc) { 1353eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_pfc pfc; 1354eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getpfc(netdev, &pfc); 1355eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) 1356eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc); 1357eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1358eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1359eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1360dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1361dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_PEER_APP, 1362dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP_UNSPEC, 1363dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP); 1364eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (err) 1365eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1366eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1367eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 13683e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_nest_end(skb, ieee); 13693e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nlmsg_end(skb, nlh); 13703e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13713e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend return rtnl_unicast(skb, &init_net, pid); 13723e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendnla_put_failure: 13733e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nlmsg_cancel(skb, nlh); 13743e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendnlmsg_failure: 13753e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend kfree_skb(skb); 13763e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend return -1; 13773e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 13783e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13796241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid/* DCBX configuration */ 13806241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, 13816241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 13826241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 13837f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 13846241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 13856241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid if (!netdev->dcbnl_ops->getdcbx) 13867f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 13876241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 13886241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, 13896241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); 13906241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 13916241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 13926241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 13936241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 13946241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, 13956241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 13966241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 13977f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 13986241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u8 value; 13996241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 14007f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setdcbx) 14017f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 14027f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 14037f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_DCBX]) 14047f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 14056241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 14066241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid value = nla_get_u8(tb[DCB_ATTR_DCBX]); 14076241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 14086241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), 14096241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, 14106241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid pid, seq, flags); 14116241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 14126241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 14136241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 14146241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 1415ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, 1416ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1417ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1418ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct sk_buff *dcbnl_skb; 1419ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlmsghdr *nlh; 1420ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct dcbmsg *dcb; 1421ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1422ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 14237f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1424ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid int getall = 0; 1425ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 14267f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->getfeatcfg) 14277f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 14287f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 14297f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 14307f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1431ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1432ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1433ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 14347f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1435ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1436ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1437ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1438ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!dcbnl_skb) { 14397f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -ENOBUFS; 1440ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1441ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1442ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1443ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1444ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1445ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb = NLMSG_DATA(nlh); 1446ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->dcb_family = AF_UNSPEC; 1447ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->cmd = DCB_CMD_GFEATCFG; 1448ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1449ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); 1450ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!nest) { 14517f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -EMSGSIZE; 14527f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 1453ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1454ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1455ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[DCB_FEATCFG_ATTR_ALL]) 1456ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid getall = 1; 1457ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1458ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1459ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!getall && !data[i]) 1460ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1461ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1462ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 14637f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!ret) 1464ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_put_u8(dcbnl_skb, i, value); 1465ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 14667f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) { 14677f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nla_nest_cancel(dcbnl_skb, nest); 14687f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 14697f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid } 1470ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1471ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nla_nest_end(dcbnl_skb, nest); 1472ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1473ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlmsg_end(dcbnl_skb, nlh); 1474ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 14757f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return rtnl_unicast(dcbnl_skb, &init_net, pid); 14767f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravidnla_put_failure: 14777f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nlmsg_cancel(dcbnl_skb, nlh); 1478ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidnlmsg_failure: 1479ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid kfree_skb(dcbnl_skb); 1480ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr_out: 1481ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1482ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1483ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1484ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, 1485ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1486ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1487ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 14887f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1489ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 1490ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 14917f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setfeatcfg) 14927f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -ENOTSUPP; 14937f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 14947f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 14957f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1496ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1497ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1498ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 1499ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15007f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1501ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err; 1502ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1503ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1504ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[i] == NULL) 1505ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1506ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1507ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid value = nla_get_u8(data[i]); 1508ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1509ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); 1510ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1511ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (ret) 15127f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto err; 1513ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1514ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr: 15157f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, 15167f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid pid, seq, flags); 15177f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 1518ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1519ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1520ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1521dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid/* Handle CEE DCBX GET commands. */ 1522dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1523dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid u32 pid, u32 seq, u16 flags) 1524dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid{ 1525dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct sk_buff *skb; 1526dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct nlmsghdr *nlh; 1527dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct dcbmsg *dcb; 1528dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct nlattr *cee; 1529dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1530dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int err; 1531dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1532dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!ops) 1533dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -EOPNOTSUPP; 1534dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1535dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1536dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!skb) 1537dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -ENOBUFS; 1538dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1539dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1540dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1541dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb = NLMSG_DATA(nlh); 1542dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->dcb_family = AF_UNSPEC; 1543dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->cmd = DCB_CMD_CEE_GET; 1544dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1545dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); 1546dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1547dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid cee = nla_nest_start(skb, DCB_ATTR_CEE); 1548dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!cee) 1549dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid goto nla_put_failure; 1550dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1551dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid /* get peer info if available */ 1552dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (ops->cee_peer_getpg) { 1553dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct cee_pg pg; 1554dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = ops->cee_peer_getpg(netdev, &pg); 1555dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!err) 1556dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg); 1557dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid } 1558dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1559dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (ops->cee_peer_getpfc) { 1560dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct cee_pfc pfc; 1561dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = ops->cee_peer_getpfc(netdev, &pfc); 1562dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!err) 1563dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc); 1564dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid } 1565dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1566dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1567dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1568dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_CEE_PEER_APP_TABLE, 1569dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_CEE_PEER_APP_INFO, 1570dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_CEE_PEER_APP); 1571dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (err) 1572dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid goto nla_put_failure; 1573dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid } 1574dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1575dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nla_nest_end(skb, cee); 1576dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlmsg_end(skb, nlh); 1577dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1578dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return rtnl_unicast(skb, &init_net, pid); 1579dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidnla_put_failure: 1580dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlmsg_cancel(skb, nlh); 1581dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidnlmsg_failure: 1582dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid kfree_skb(skb); 1583dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -1; 1584dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid} 1585dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 15862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 15872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 15882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 15892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 15902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); 15912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 15922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid = skb ? NETLINK_CB(skb).pid : 0; 15932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 15942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 159509ad9bc752519cc167d0a573e1acf69b5c707c67Octavian Purdila if (!net_eq(net, &init_net)) 15962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 15972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 15982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 15992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 16002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 16012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 16022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 16042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 16052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 16072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 16082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 16092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops) 16112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 16122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck switch (dcb->cmd) { 16142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GSTATE: 16152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, 16162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_GCFG: 16192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 16202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GPERM_HWADDR: 16232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, 16242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_GCFG: 16272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 16282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_GCFG: 16312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 16322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 1634859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_GCFG: 1635859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 1636859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1637859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 16382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SSTATE: 16392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, 16402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_SCFG: 16432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 16442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SET_ALL: 16482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, 16492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_SCFG: 16522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 16532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 16552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_SCFG: 16562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 16572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 16582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 165946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck case DCB_CMD_GCAP: 166046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, 166146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh->nlmsg_flags); 166246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto out; 166333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_GNUMTCS: 166433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 166533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 166633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 166733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_SNUMTCS: 166833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 166933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 167033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 16710eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_GSTATE: 16720eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 16730eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 16740eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 16750eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_SSTATE: 16760eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 16770eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 16780eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 1679859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_SCFG: 1680859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 1681859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1682859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 1683579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_GAPP: 1684579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, 1685579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1686579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 1687579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_SAPP: 1688579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1689579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1690579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 16913e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_SET: 16923e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, 16933e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nlh->nlmsg_flags); 16943e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 16953e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_GET: 16963e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, 16973e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nlh->nlmsg_flags); 16983e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 16996241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_GDCBX: 17006241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, 17016241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 17026241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 17036241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_SDCBX: 17046241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, 17056241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 17066241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 1707ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_GFEATCFG: 1708ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 1709ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 1710ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 1711ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_SFEATCFG: 1712ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 1713ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 1714ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 1715dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid case DCB_CMD_CEE_GET: 1716dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, 1717dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlh->nlmsg_flags); 1718dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid goto out; 17192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck default: 17202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 17212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 17222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerrout: 17232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 17242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 17252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 17262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 17272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 17282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 17299ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 17309ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * dcb_getapp - retrieve the DCBX application user priority 17319ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 17329ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * On success returns a non-zero 802.1p user priority bitmap 17339ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * otherwise returns 0 as the invalid user priority bitmap to 17349ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * indicate an error. 17359ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 17369ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_getapp(struct net_device *dev, struct dcb_app *app) 17379ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17389ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17399ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend u8 prio = 0; 17409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17419ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 17429ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 17439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == app->selector && 17449ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == app->protocol && 17459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) { 17469ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend prio = itr->app.priority; 17479ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend break; 17489ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17499ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17509ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 17519ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17529ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return prio; 17539ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 17549ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_getapp); 17559ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17569ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 17579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * ixgbe_dcbnl_setapp - add dcb application data to app list 17589ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 17599ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * Priority 0 is the default priority this removes applications 17609ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * from the app list if the priority is set to zero. 17619ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 17629ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_setapp(struct net_device *dev, struct dcb_app *new) 17639ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17649ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17657ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend struct dcb_app_type event; 17667ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend 17677ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.name, dev->name, sizeof(event.name)); 17687ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.app, new, sizeof(event.app)); 17699ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17709ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 17719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* Search for existing match and replace */ 17729ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 17739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == new->selector && 17749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == new->protocol && 17759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) { 17769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) 17779ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.priority = new->priority; 17789ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend else { 17799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&itr->list); 17809ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(itr); 17819ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17829ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto out; 17839ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17849ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17859ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* App type does not exist add new application type */ 17869ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) { 17879ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *entry; 17889ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); 17899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!entry) { 17909ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 17919ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return -ENOMEM; 17929ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend memcpy(&entry->app, new, sizeof(*new)); 17959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend strncpy(entry->name, dev->name, IFNAMSIZ); 17969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_add(&entry->list, &dcb_app_list); 17979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 17989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendout: 17999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 18007ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 18019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return 0; 18029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 18039ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_setapp); 18049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 18057c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6Shmulik Ravidstatic void dcb_flushapp(void) 18069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 18079ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *app; 18082a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter struct dcb_app_type *tmp; 18099ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 18109ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 18112a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { 18129ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&app->list); 18139ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(app); 18149ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 18159ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 18169ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 18179ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 18182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 18192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 18209ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend INIT_LIST_HEAD(&dcb_app_list); 18219ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 18222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL); 18232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL); 18242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 18252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 18262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 18272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 18282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 18292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 18302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 18312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 18322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 18339ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend dcb_flushapp(); 18342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 18352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 1836