linux/net/dcb/dcbnl.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2008-2011, Intel Corporation.
 *
 * Description: Data Center Bridging netlink interface
 * Author: Lucy Liu <[email protected]>
 */

#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/slab.h>
#include <net/netlink.h>
#include <net/rtnetlink.h>
#include <linux/dcbnl.h>
#include <net/dcbevent.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
#include <net/sock.h>

/* Data Center Bridging (DCB) is a collection of Ethernet enhancements
 * intended to allow network traffic with differing requirements
 * (highly reliable, no drops vs. best effort vs. low latency) to operate
 * and co-exist on Ethernet.  Current DCB features are:
 *
 * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a
 *   framework for assigning bandwidth guarantees to traffic classes.
 *
 * Priority-based Flow Control (PFC) - provides a flow control mechanism which
 *   can work independently for each 802.1p priority.
 *
 * Congestion Notification - provides a mechanism for end-to-end congestion
 *   control for protocols which do not have built-in congestion management.
 *
 * More information about the emerging standards for these Ethernet features
 * can be found at: http://www.ieee802.org/1/pages/dcbridges.html
 *
 * This file implements an rtnetlink interface to allow configuration of DCB
 * features for capable devices.
 */

/**************** DCB attribute policies *************************************/

/* DCB netlink attributes policy */
static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] =;

/* DCB priority flow control to User Priority nested attributes */
static const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] =;

/* DCB priority grouping nested attributes */
static const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] =;

/* DCB traffic class nested attributes. */
static const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] =;

/* DCB capabilities nested attributes. */
static const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] =;

/* DCB capabilities nested attributes. */
static const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] =;

/* DCB BCN nested attributes. */
static const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] =;

/* DCB APP nested attributes. */
static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] =;

/* IEEE 802.1Qaz nested attributes. */
static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] =;

/* DCB number of traffic classes nested attributes. */
static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] =;

static LIST_HEAD(dcb_app_list);
static LIST_HEAD(dcb_rewr_list);
static DEFINE_SPINLOCK(dcb_lock);

static enum ieee_attrs_app dcbnl_app_attr_type_get(u8 selector)
{}

static bool dcbnl_app_attr_type_validate(enum ieee_attrs_app type)
{}

static bool dcbnl_app_selector_validate(enum ieee_attrs_app type, u8 selector)
{}

static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq,
				    u32 flags, struct nlmsghdr **nlhp)
{}

static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh,
			  u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
			   u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
				u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh,
			u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
			   u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
			   u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh,
			u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh,
			u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     struct nlattr **tb, struct sk_buff *skb, int dir)
{}

static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh,
			  u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
			   u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh,
			u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb,
			     int dir)
{}

static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			     u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			    u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			    u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
				int app_nested_type, int app_info_type,
				int app_entry_type)
{}

static int dcbnl_getapptrust(struct net_device *netdev, struct sk_buff *skb)
{}

/* Set or delete APP table or rewrite table entries. The APP struct is validated
 * and the appropriate callback function is called.
 */
static int dcbnl_app_table_setdel(struct nlattr *attr,
				  struct net_device *netdev,
				  int (*setdel)(struct net_device *dev,
						struct dcb_app *app))
{}

/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb GET commands. */
static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
{}

static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
			     int dir)
{}

static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
{}

static int dcbnl_notify(struct net_device *dev, int event, int cmd,
			u32 seq, u32 portid, int dcbx_ver)
{}

int dcbnl_ieee_notify(struct net_device *dev, int event, int cmd,
		      u32 seq, u32 portid)
{}
EXPORT_SYMBOL();

int dcbnl_cee_notify(struct net_device *dev, int event, int cmd,
		     u32 seq, u32 portid)
{}
EXPORT_SYMBOL();

/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb SET commands.
 * If any requested operation can not be completed
 * the entire msg is aborted and error value is returned.
 * No attempt is made to reconcile the case where only part of the
 * cmd can be completed.
 */
static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
			  u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh,
			  u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh,
			  u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}


/* DCBX configuration */
static int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh,
			 u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh,
			 u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			    u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
			    u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

/* Handle CEE DCBX GET commands. */
static int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh,
			 u32 seq, struct nlattr **tb, struct sk_buff *skb)
{}

struct reply_func {};

static const struct reply_func reply_funcs[DCB_CMD_MAX+1] =;

static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
		    struct netlink_ext_ack *extack)
{}

static struct dcb_app_type *dcb_rewr_lookup(const struct dcb_app *app,
					    int ifindex, int proto)
{}

static struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app,
					   int ifindex, int prio)
{}

static int dcb_app_add(struct list_head *list, const struct dcb_app *app,
		       int ifindex)
{}

/**
 * dcb_getapp - retrieve the DCBX application user priority
 * @dev: network interface
 * @app: application to get user priority of
 *
 * On success returns a non-zero 802.1p user priority bitmap
 * otherwise returns 0 as the invalid user priority bitmap to
 * indicate an error.
 */
u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
{}
EXPORT_SYMBOL();

/**
 * dcb_setapp - add CEE dcb application data to app list
 * @dev: network interface
 * @new: application data to add
 *
 * Priority 0 is an invalid priority in CEE spec. This routine
 * removes applications from the app list if the priority is
 * set to zero. Priority is expected to be 8-bit 802.1p user priority bitmap
 */
int dcb_setapp(struct net_device *dev, struct dcb_app *new)
{}
EXPORT_SYMBOL();

/**
 * dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority
 * @dev: network interface
 * @app: where to store the retrieve application data
 *
 * Helper routine which on success returns a non-zero 802.1Qaz user
 * priority bitmap otherwise returns 0 to indicate the dcb_app was
 * not found in APP list.
 */
u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app)
{}
EXPORT_SYMBOL();

/* Get protocol value from rewrite entry. */
u16 dcb_getrewr(struct net_device *dev, struct dcb_app *app)
{}
EXPORT_SYMBOL();

 /* Add rewrite entry to the rewrite list. */
int dcb_setrewr(struct net_device *dev, struct dcb_app *new)
{}
EXPORT_SYMBOL();

/* Delete rewrite entry from the rewrite list. */
int dcb_delrewr(struct net_device *dev, struct dcb_app *del)
{}
EXPORT_SYMBOL();

/**
 * dcb_ieee_setapp - add IEEE dcb application data to app list
 * @dev: network interface
 * @new: application data to add
 *
 * This adds Application data to the list. Multiple application
 * entries may exists for the same selector and protocol as long
 * as the priorities are different. Priority is expected to be a
 * 3-bit unsigned integer
 */
int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new)
{}
EXPORT_SYMBOL();

/**
 * dcb_ieee_delapp - delete IEEE dcb application data from list
 * @dev: network interface
 * @del: application data to delete
 *
 * This removes a matching APP data from the APP list
 */
int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
{}
EXPORT_SYMBOL();

/* dcb_getrewr_prio_pcp_mask_map - For a given device, find mapping from
 * priorities to the PCP and DEI values assigned to that priority.
 */
void dcb_getrewr_prio_pcp_mask_map(const struct net_device *dev,
				   struct dcb_rewr_prio_pcp_map *p_map)
{}
EXPORT_SYMBOL();

/* dcb_getrewr_prio_dscp_mask_map - For a given device, find mapping from
 * priorities to the DSCP values assigned to that priority.
 */
void dcb_getrewr_prio_dscp_mask_map(const struct net_device *dev,
				    struct dcb_ieee_app_prio_map *p_map)
{}
EXPORT_SYMBOL();

/*
 * dcb_ieee_getapp_prio_dscp_mask_map - For a given device, find mapping from
 * priorities to the DSCP values assigned to that priority. Initialize p_map
 * such that each map element holds a bit mask of DSCP values configured for
 * that priority by APP entries.
 */
void dcb_ieee_getapp_prio_dscp_mask_map(const struct net_device *dev,
					struct dcb_ieee_app_prio_map *p_map)
{}
EXPORT_SYMBOL();

/*
 * dcb_ieee_getapp_dscp_prio_mask_map - For a given device, find mapping from
 * DSCP values to the priorities assigned to that DSCP value. Initialize p_map
 * such that each map element holds a bit mask of priorities configured for a
 * given DSCP value by APP entries.
 */
void
dcb_ieee_getapp_dscp_prio_mask_map(const struct net_device *dev,
				   struct dcb_ieee_app_dscp_map *p_map)
{}
EXPORT_SYMBOL();

/*
 * Per 802.1Q-2014, the selector value of 1 is used for matching on Ethernet
 * type, with valid PID values >= 1536. A special meaning is then assigned to
 * protocol value of 0: "default priority. For use when priority is not
 * otherwise specified".
 *
 * dcb_ieee_getapp_default_prio_mask - For a given device, find all APP entries
 * of the form {$PRIO, ETHERTYPE, 0} and construct a bit mask of all default
 * priorities set by these entries.
 */
u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
{}
EXPORT_SYMBOL();

static void dcbnl_flush_dev(struct net_device *dev)
{}

static int dcbnl_netdevice_event(struct notifier_block *nb,
				 unsigned long event, void *ptr)
{}

static struct notifier_block dcbnl_nb __read_mostly =;

static int __init dcbnl_init(void)
{}
device_initcall(dcbnl_init);