dcbnl.c revision b54452b07a7b1b8cc1385edba3ef2ef6d4679d5a
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> 222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/netlink.h> 232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/rtnetlink.h> 242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/dcbnl.h> 252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/rtnetlink.h> 262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/sock.h> 272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/** 292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Data Center Bridging (DCB) is a collection of Ethernet enhancements 302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * intended to allow network traffic with differing requirements 312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * (highly reliable, no drops vs. best effort vs. low latency) to operate 322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * and co-exist on Ethernet. Current DCB features are: 332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a 352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * framework for assigning bandwidth guarantees to traffic classes. 362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Priority-based Flow Control (PFC) - provides a flow control mechanism which 382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can work independently for each 802.1p priority. 392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Congestion Notification - provides a mechanism for end-to-end congestion 412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * control for protocols which do not have built-in congestion management. 422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * More information about the emerging standards for these Ethernet features 442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can be found at: http://www.ieee802.org/1/pages/dcbridges.html 452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This file implements an rtnetlink interface to allow configuration of DCB 472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * features for capable devices. 482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck */ 492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_AUTHOR("Lucy Liu, <lucy.liu@intel.com>"); 517a6b6f515f77d1c62a2f383b6dce18cb0af0cf4fJeff KirsherMODULE_DESCRIPTION("Data Center Bridging netlink interface"); 522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_LICENSE("GPL"); 532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/**************** DCB attribute policies *************************************/ 552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB netlink attributes policy */ 57b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { 58859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, 59859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_STATE] = {.type = NLA_U8}, 60859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, 61859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED}, 62859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, 632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, 64859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_CAP] = {.type = NLA_NESTED}, 65859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 66859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 676fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_ATTR_APP] = {.type = NLA_NESTED}, 682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority flow control to User Priority nested attributes */ 71b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { 722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, 732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, 742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, 752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_3] = {.type = NLA_U8}, 762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_4] = {.type = NLA_U8}, 772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_5] = {.type = NLA_U8}, 782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_6] = {.type = NLA_U8}, 792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_7] = {.type = NLA_U8}, 802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG}, 812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority grouping nested attributes */ 84b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { 852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, 862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, 872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, 882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_3] = {.type = NLA_NESTED}, 892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_4] = {.type = NLA_NESTED}, 902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_5] = {.type = NLA_NESTED}, 912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_6] = {.type = NLA_NESTED}, 922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_7] = {.type = NLA_NESTED}, 932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_ALL] = {.type = NLA_NESTED}, 942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_0] = {.type = NLA_U8}, 952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_1] = {.type = NLA_U8}, 962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_2] = {.type = NLA_U8}, 972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_3] = {.type = NLA_U8}, 982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_4] = {.type = NLA_U8}, 992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_5] = {.type = NLA_U8}, 1002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_6] = {.type = NLA_U8}, 1012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_7] = {.type = NLA_U8}, 1022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_ALL] = {.type = NLA_FLAG}, 1032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB traffic class nested attributes. */ 106b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { 1072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, 1082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, 1092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, 1102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_BW_PCT] = {.type = NLA_U8}, 1112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG}, 1122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck/* DCB capabilities nested attributes. */ 115b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { 11646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, 11746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, 11846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, 11946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8}, 12046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8}, 12146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, 12246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, 12346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, 12446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck}; 1252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck/* DCB capabilities nested attributes. */ 127b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { 12833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, 12933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, 13033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, 13133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck}; 13233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 133859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck/* DCB BCN nested attributes. */ 134b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { 135859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, 136859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, 137859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, 138859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_3] = {.type = NLA_U8}, 139859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_4] = {.type = NLA_U8}, 140859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_5] = {.type = NLA_U8}, 141859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_6] = {.type = NLA_U8}, 142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_7] = {.type = NLA_U8}, 143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG}, 144f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32}, 145f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_1] = {.type = NLA_U32}, 146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALPHA] = {.type = NLA_U32}, 147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_BETA] = {.type = NLA_U32}, 148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GD] = {.type = NLA_U32}, 149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GI] = {.type = NLA_U32}, 150859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TMAX] = {.type = NLA_U32}, 151859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TD] = {.type = NLA_U32}, 152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RMIN] = {.type = NLA_U32}, 153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_W] = {.type = NLA_U32}, 154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RD] = {.type = NLA_U32}, 155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RU] = {.type = NLA_U32}, 156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_WRTT] = {.type = NLA_U32}, 157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RI] = {.type = NLA_U32}, 158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_C] = {.type = NLA_U32}, 159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG}, 160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck}; 161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1626fa382af61338908e5713234bcee598423f661c3Yi Zou/* DCB APP nested attributes. */ 163b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { 1646fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, 1656fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_ID] = {.type = NLA_U16}, 1666fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 1676fa382af61338908e5713234bcee598423f661c3Yi Zou}; 1686fa382af61338908e5713234bcee598423f661c3Yi Zou 1692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* standard netlink reply call */ 1702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 1712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 seq, u16 flags) 1722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 1732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 1742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 1752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 1762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 1772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 1802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 1812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); 1832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 1852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 1862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = cmd; 1872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_pad = 0; 1882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, attr, value); 1902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 1912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 1922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* end the message, assign the nlmsg_len. */ 1942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 1952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 1962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 1977eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend return -EINVAL; 1982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 2012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 202858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 2032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, 2072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB, 2162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags); 2172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, 2222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) 2342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 2472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_PFC_GCFG; 2512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); 2532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, nest); 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 2752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2787eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 2792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 283858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 2842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 2852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, 2892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 2952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 2982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 3022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 3032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 3052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 3072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 3082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_GPERM_HWADDR; 3092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 3112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), 3132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck perm_addr); 3142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3197eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 324858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 32946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckstatic int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, 33046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u32 pid, u32 seq, u16 flags) 33146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 33246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct sk_buff *dcbnl_skb; 33346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlmsghdr *nlh; 33446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct dcbmsg *dcb; 33546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 33646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 33746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int ret = -EINVAL; 33846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 33946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 34046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 34146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) 34246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return ret; 34346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 34446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 34546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 34646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 34746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 34846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 34946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 35046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!dcbnl_skb) 35146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 35246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 35346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 35446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 35546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb = NLMSG_DATA(nlh); 35646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->dcb_family = AF_UNSPEC; 35746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->cmd = DCB_CMD_GCAP; 35846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 35946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); 36046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 36146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 36246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 36346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 36446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 36546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 36646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 36746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 36846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 36946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 37146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 37246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 37446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 37546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 37646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 37746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 37846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 37946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_end(dcbnl_skb, nest); 38046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 38246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 38446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 3857eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 38646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 38846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duycknlmsg_failure: 38946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr: 390858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 39146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr_out: 39246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return -EINVAL; 39346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 39446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, 39633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 39733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 39833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct sk_buff *dcbnl_skb; 39933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlmsghdr *nlh; 40033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct dcbmsg *dcb; 40133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 40233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 40333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 40433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 40533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 40633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) 40833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 40933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 41033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 41133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 41233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 41333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 41433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 41533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 41633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 41733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 41833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!dcbnl_skb) { 41933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 42033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 42133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 42233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 42333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 42433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 42533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb = NLMSG_DATA(nlh); 42633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->dcb_family = AF_UNSPEC; 42733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->cmd = DCB_CMD_GNUMTCS; 42833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 42933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); 43033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!nest) { 43133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 43233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 43333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 43433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 43633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 43733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 43933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 44033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 44133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 44333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 44433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 44533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 44733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 44833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 45033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } else { 45233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 45333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_end(dcbnl_skb, nest); 45633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 45833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 46033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 46133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 4627eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 46333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 46433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 46633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duycknlmsg_failure: 46733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 468858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 46933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr_out: 47033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 47133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 47233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, 47433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 47533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 47633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 47733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 47833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 47933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 48033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 4818b124a8e14c04378466ddfe63e41fc5035f957ebDon Skidmore if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) 48233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 48333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 48533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 48633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 48833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 48933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 49033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 49133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 49333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 49433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 49533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 49733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 49933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 50133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto operr; 50233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 50333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckoperr: 50533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS, 50633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck DCB_ATTR_NUMTCS, pid, seq, flags); 50733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 50933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 51033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 51133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5120eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, 5130eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5140eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5150eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5160eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5170eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 5180eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5190eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5200eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, 5210eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, 5220eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5230eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5240eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5250eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5260eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5270eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, 5280eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5290eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5300eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5310eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 5320eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5330eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) 5340eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5350eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5360eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 5370eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5380eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 5390eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5400eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, 5410eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5440eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5450eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 546579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, 547579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 548579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 549579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct sk_buff *dcbnl_skb; 550579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlmsghdr *nlh; 551579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct dcbmsg *dcb; 552579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 553579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 554579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 555579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 556579496865cf4ea429146382d62047ffdbaab0deeYi Zou int ret = -EINVAL; 557579496865cf4ea429146382d62047ffdbaab0deeYi Zou 558579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp) 559579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 560579496865cf4ea429146382d62047ffdbaab0deeYi Zou 561579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 562579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 563579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 564579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 565579496865cf4ea429146382d62047ffdbaab0deeYi Zou 566579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 567579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 568579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 569579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 570579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 571579496865cf4ea429146382d62047ffdbaab0deeYi Zou 572579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 573579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 574579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 575579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 576579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 577579496865cf4ea429146382d62047ffdbaab0deeYi Zou 578579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 579579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 580579496865cf4ea429146382d62047ffdbaab0deeYi Zou 581579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* send this back */ 582579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 583579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!dcbnl_skb) 584579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 585579496865cf4ea429146382d62047ffdbaab0deeYi Zou 586579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 587579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb = NLMSG_DATA(nlh); 588579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->dcb_family = AF_UNSPEC; 589579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->cmd = DCB_CMD_GAPP; 590579496865cf4ea429146382d62047ffdbaab0deeYi Zou 591579496865cf4ea429146382d62047ffdbaab0deeYi Zou app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); 592579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); 593579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 594579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 595579496865cf4ea429146382d62047ffdbaab0deeYi Zou 596579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); 597579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 598579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 599579496865cf4ea429146382d62047ffdbaab0deeYi Zou 600579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); 601579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 602579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 603579496865cf4ea429146382d62047ffdbaab0deeYi Zou 604579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_end(dcbnl_skb, app_nest); 605579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlmsg_end(dcbnl_skb, nlh); 606579496865cf4ea429146382d62047ffdbaab0deeYi Zou 607579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 608579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 609579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto nlmsg_failure; 610579496865cf4ea429146382d62047ffdbaab0deeYi Zou 611579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 612579496865cf4ea429146382d62047ffdbaab0deeYi Zou 613579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 614579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_cancel(dcbnl_skb, app_nest); 615579496865cf4ea429146382d62047ffdbaab0deeYi Zounlmsg_failure: 616579496865cf4ea429146382d62047ffdbaab0deeYi Zou kfree_skb(dcbnl_skb); 617579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 618579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 619579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 620579496865cf4ea429146382d62047ffdbaab0deeYi Zou 621579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 622579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 623579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 624579496865cf4ea429146382d62047ffdbaab0deeYi Zou int ret = -EINVAL; 625579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 626579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 627579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 628579496865cf4ea429146382d62047ffdbaab0deeYi Zou 629579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp) 630579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 631579496865cf4ea429146382d62047ffdbaab0deeYi Zou 632579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 633579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 634579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 635579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 636579496865cf4ea429146382d62047ffdbaab0deeYi Zou 637579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 638579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 639579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 640579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 641579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 642579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 643579496865cf4ea429146382d62047ffdbaab0deeYi Zou 644579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 645579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 646579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 647579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 648579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 649579496865cf4ea429146382d62047ffdbaab0deeYi Zou 650579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 651579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 652579496865cf4ea429146382d62047ffdbaab0deeYi Zou 653579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up), 654579496865cf4ea429146382d62047ffdbaab0deeYi Zou RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 655579496865cf4ea429146382d62047ffdbaab0deeYi Zou pid, seq, flags); 656579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 657579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 658579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 659579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, 6612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 6622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 6632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 6642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 6652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 6662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 6672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 6682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 6692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 6702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 6712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 6722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 6732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 6752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgtx || 6762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 6772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 6782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 6792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 6802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 6822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 6832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 6862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 6892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 6902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 6922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 6942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 6952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG; 6962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); 6982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 6992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 7002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 7032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 7062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 7102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 7112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 7122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 7132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 7142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_nest = nla_nest_start(dcbnl_skb, i); 7182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 7192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 7222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 7232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 7242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 7272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 7282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 7292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 7322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 7332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 7342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 7532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 7562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 7602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, 7622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 7632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, param_nest); 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 7702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 7712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 7722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 7732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 7812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 7822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 7832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 7842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 7852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 7862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 7872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 7882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, tc_pct); 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, pg_nest); 7962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8017eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 8022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, param_nest); 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, pg_nest); 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 811858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8401486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), 8411486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE, 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 8512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 8592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 8602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 8612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 8632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 8652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 8682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 8692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 8702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, 8732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 8742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 8752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, 8792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) 8842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, 8872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); 8882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, 8932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 8942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 8962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 8972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 8992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 9002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 9012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 9022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 9032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 9052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgtx || 9062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 9072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 9082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 9092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 9122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 9132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 9172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 9182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 9212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 9222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 9262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 9272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 9282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 9292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 9312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 9322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 9332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 9352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 9362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 9382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 9392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 9412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 9422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 9432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 9452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 9462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 9472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 9482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 9492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 9502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 9512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 9522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 9532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 9542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 9552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 9592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 9602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 9632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 9652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 9662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 9672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 9682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 9692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 9702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 9712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 9722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 9732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, 9772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 9782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_ATTR_PG_CFG, pid, seq, flags); 9792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 9812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, 9852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); 9882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, 9912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); 9942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 996859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, 997859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 998859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 999859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct sk_buff *dcbnl_skb; 1000859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlmsghdr *nlh; 1001859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct dcbmsg *dcb; 1002859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 1003859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 1004859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1005859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 1006859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1007859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 1008859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1009859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1010859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || 1011859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 1012859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1013859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1014859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 1015859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 1016859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1017859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1018859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1019859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1020859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1021859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!dcbnl_skb) 1022859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1023859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1024859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1025859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1026859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb = NLMSG_DATA(nlh); 1027859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->dcb_family = AF_UNSPEC; 1028859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->cmd = DCB_CMD_BCN_GCFG; 1029859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1030859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); 1031859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 1032859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1033859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1034859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 1035859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 1036859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1037859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1038859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1039859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1040859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1041859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 1042859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 1043859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value_byte); 1044859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1045859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1046859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1047859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1048f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1049859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1050859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1051859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1052859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 1053859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 1054859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u32(dcbnl_skb, i, value_integer); 1055859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1056859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1057859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1058859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1059859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_end(dcbnl_skb, bcn_nest); 1060859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1061859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 1062859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1063859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 1064859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 10657eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 1066859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1067859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 1068859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1069859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 1070859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_cancel(dcbnl_skb, bcn_nest); 1071859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duycknlmsg_failure: 1072859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1073858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 1074859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_out: 1075859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = -EINVAL; 1076859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1077859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1078859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1079859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, 1080859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1081859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1082859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 1083859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1084859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1085859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1086859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 1087859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1088f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || 1089f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 1090859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1091859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1092859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 1093859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 1094859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 1095859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1096859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1097859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1098859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1099859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1100859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1101859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 1102859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 1103859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 1104859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1105859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1106f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1107859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1108859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1109859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 1110859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 1111859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 1112859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1113859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1114859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, 1115859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck pid, seq, flags); 1116859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1117859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1118859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1119859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 11202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 11212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 11222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 11232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 11242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); 11252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 11262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid = skb ? NETLINK_CB(skb).pid : 0; 11272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 11282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 112909ad9bc752519cc167d0a573e1acf69b5c707c67Octavian Purdila if (!net_eq(net, &init_net)) 11302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 11312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 11332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 11342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 11352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 11362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 11382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 11392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 11412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 11422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 11432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops) 11452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 11462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck switch (dcb->cmd) { 11482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GSTATE: 11492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, 11502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_GCFG: 11532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 11542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GPERM_HWADDR: 11572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, 11582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_GCFG: 11612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 11622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_GCFG: 11652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 11662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 1168859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_GCFG: 1169859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 1170859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1171859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 11722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SSTATE: 11732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, 11742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_SCFG: 11772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 11782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SET_ALL: 11822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, 11832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_SCFG: 11862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 11872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 11892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_SCFG: 11902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 11912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 11922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 119346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck case DCB_CMD_GCAP: 119446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, 119546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh->nlmsg_flags); 119646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto out; 119733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_GNUMTCS: 119833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 119933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 120033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 120133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_SNUMTCS: 120233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 120333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 120433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 12050eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_GSTATE: 12060eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 12070eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 12080eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 12090eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_SSTATE: 12100eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 12110eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 12120eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 1213859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_SCFG: 1214859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 1215859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1216859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 1217579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_GAPP: 1218579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, 1219579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1220579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 1221579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_SAPP: 1222579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1223579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 1224579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 12252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck default: 12262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 12272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 12282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerrout: 12292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 12302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 12312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 12322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 12332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 12342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 12362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 12372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL); 12382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL); 12392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 12412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 12422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 12432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 12452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 12462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 12472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 12482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 12492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 12502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1252