Skip to content

Commit

Permalink
net/ncsi: Add generic netlink family
Browse files Browse the repository at this point in the history
Add a generic netlink family for NCSI. This supports three commands;
NCSI_CMD_PKG_INFO which returns information on packages and their
associated channels, NCSI_CMD_SET_INTERFACE which allows a specific
package or package/channel combination to be set as the preferred
choice, and NCSI_CMD_CLEAR_INTERFACE which clears any preferred setting.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
sammj authored and davem330 committed Mar 5, 2018
1 parent be63189 commit 955dc68
Show file tree
Hide file tree
Showing 6 changed files with 586 additions and 5 deletions.
115 changes: 115 additions & 0 deletions include/uapi/linux/ncsi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/

#ifndef __UAPI_NCSI_NETLINK_H__
#define __UAPI_NCSI_NETLINK_H__

/**
* enum ncsi_nl_commands - supported NCSI commands
*
* @NCSI_CMD_UNSPEC: unspecified command to catch errors
* @NCSI_CMD_PKG_INFO: list package and channel attributes. Requires
* NCSI_ATTR_IFINDEX. If NCSI_ATTR_PACKAGE_ID is specified returns the
* specific package and its channels - otherwise a dump request returns
* all packages and their associated channels.
* @NCSI_CMD_SET_INTERFACE: set preferred package and channel combination.
* Requires NCSI_ATTR_IFINDEX and the preferred NCSI_ATTR_PACKAGE_ID and
* optionally the preferred NCSI_ATTR_CHANNEL_ID.
* @NCSI_CMD_CLEAR_INTERFACE: clear any preferred package/channel combination.
* Requires NCSI_ATTR_IFINDEX.
* @NCSI_CMD_MAX: highest command number
*/
enum ncsi_nl_commands {
NCSI_CMD_UNSPEC,
NCSI_CMD_PKG_INFO,
NCSI_CMD_SET_INTERFACE,
NCSI_CMD_CLEAR_INTERFACE,

__NCSI_CMD_AFTER_LAST,
NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
};

/**
* enum ncsi_nl_attrs - General NCSI netlink attributes
*
* @NCSI_ATTR_UNSPEC: unspecified attributes to catch errors
* @NCSI_ATTR_IFINDEX: ifindex of network device using NCSI
* @NCSI_ATTR_PACKAGE_LIST: nested array of NCSI_PKG_ATTR attributes
* @NCSI_ATTR_PACKAGE_ID: package ID
* @NCSI_ATTR_CHANNEL_ID: channel ID
* @NCSI_ATTR_MAX: highest attribute number
*/
enum ncsi_nl_attrs {
NCSI_ATTR_UNSPEC,
NCSI_ATTR_IFINDEX,
NCSI_ATTR_PACKAGE_LIST,
NCSI_ATTR_PACKAGE_ID,
NCSI_ATTR_CHANNEL_ID,

__NCSI_ATTR_AFTER_LAST,
NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
};

/**
* enum ncsi_nl_pkg_attrs - NCSI netlink package-specific attributes
*
* @NCSI_PKG_ATTR_UNSPEC: unspecified attributes to catch errors
* @NCSI_PKG_ATTR: nested array of package attributes
* @NCSI_PKG_ATTR_ID: package ID
* @NCSI_PKG_ATTR_FORCED: flag signifying a package has been set as preferred
* @NCSI_PKG_ATTR_CHANNEL_LIST: nested array of NCSI_CHANNEL_ATTR attributes
* @NCSI_PKG_ATTR_MAX: highest attribute number
*/
enum ncsi_nl_pkg_attrs {
NCSI_PKG_ATTR_UNSPEC,
NCSI_PKG_ATTR,
NCSI_PKG_ATTR_ID,
NCSI_PKG_ATTR_FORCED,
NCSI_PKG_ATTR_CHANNEL_LIST,

__NCSI_PKG_ATTR_AFTER_LAST,
NCSI_PKG_ATTR_MAX = __NCSI_PKG_ATTR_AFTER_LAST - 1
};

/**
* enum ncsi_nl_channel_attrs - NCSI netlink channel-specific attributes
*
* @NCSI_CHANNEL_ATTR_UNSPEC: unspecified attributes to catch errors
* @NCSI_CHANNEL_ATTR: nested array of channel attributes
* @NCSI_CHANNEL_ATTR_ID: channel ID
* @NCSI_CHANNEL_ATTR_VERSION_MAJOR: channel major version number
* @NCSI_CHANNEL_ATTR_VERSION_MINOR: channel minor version number
* @NCSI_CHANNEL_ATTR_VERSION_STR: channel version string
* @NCSI_CHANNEL_ATTR_LINK_STATE: channel link state flags
* @NCSI_CHANNEL_ATTR_ACTIVE: channels with this flag are in
* NCSI_CHANNEL_ACTIVE state
* @NCSI_CHANNEL_ATTR_FORCED: flag signifying a channel has been set as
* preferred
* @NCSI_CHANNEL_ATTR_VLAN_LIST: nested array of NCSI_CHANNEL_ATTR_VLAN_IDs
* @NCSI_CHANNEL_ATTR_VLAN_ID: VLAN ID being filtered on this channel
* @NCSI_CHANNEL_ATTR_MAX: highest attribute number
*/
enum ncsi_nl_channel_attrs {
NCSI_CHANNEL_ATTR_UNSPEC,
NCSI_CHANNEL_ATTR,
NCSI_CHANNEL_ATTR_ID,
NCSI_CHANNEL_ATTR_VERSION_MAJOR,
NCSI_CHANNEL_ATTR_VERSION_MINOR,
NCSI_CHANNEL_ATTR_VERSION_STR,
NCSI_CHANNEL_ATTR_LINK_STATE,
NCSI_CHANNEL_ATTR_ACTIVE,
NCSI_CHANNEL_ATTR_FORCED,
NCSI_CHANNEL_ATTR_VLAN_LIST,
NCSI_CHANNEL_ATTR_VLAN_ID,

__NCSI_CHANNEL_ATTR_AFTER_LAST,
NCSI_CHANNEL_ATTR_MAX = __NCSI_CHANNEL_ATTR_AFTER_LAST - 1
};

#endif /* __UAPI_NCSI_NETLINK_H__ */
2 changes: 1 addition & 1 deletion net/ncsi/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#
# Makefile for NCSI API
#
obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o
obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o ncsi-netlink.o
3 changes: 3 additions & 0 deletions net/ncsi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ struct ncsi_dev_priv {
unsigned int package_num; /* Number of packages */
struct list_head packages; /* List of packages */
struct ncsi_channel *hot_channel; /* Channel was ever active */
struct ncsi_package *force_package; /* Force a specific package */
struct ncsi_channel *force_channel; /* Force a specific channel */
struct ncsi_request requests[256]; /* Request table */
unsigned int request_id; /* Last used request ID */
#define NCSI_REQ_START_IDX 1
Expand Down Expand Up @@ -318,6 +320,7 @@ extern spinlock_t ncsi_dev_lock;
list_for_each_entry_rcu(nc, &np->channels, node)

/* Resources */
u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index);
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
Expand Down
30 changes: 26 additions & 4 deletions net/ncsi/ncsi-manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>

#include <net/ncsi.h>
#include <net/net_namespace.h>
Expand All @@ -23,6 +22,7 @@

#include "internal.h"
#include "ncsi-pkt.h"
#include "ncsi-netlink.h"

LIST_HEAD(ncsi_dev_list);
DEFINE_SPINLOCK(ncsi_dev_lock);
Expand All @@ -38,7 +38,7 @@ static inline int ncsi_filter_size(int table)
return sizes[table];
}

static u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
{
struct ncsi_channel_filter *ncf;
int size;
Expand Down Expand Up @@ -965,20 +965,37 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)

static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
{
struct ncsi_package *np;
struct ncsi_channel *nc, *found, *hot_nc;
struct ncsi_package *np, *force_package;
struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
struct ncsi_channel_mode *ncm;
unsigned long flags;

spin_lock_irqsave(&ndp->lock, flags);
hot_nc = ndp->hot_channel;
force_channel = ndp->force_channel;
force_package = ndp->force_package;
spin_unlock_irqrestore(&ndp->lock, flags);

/* Force a specific channel whether or not it has link if we have been
* configured to do so
*/
if (force_package && force_channel) {
found = force_channel;
ncm = &found->modes[NCSI_MODE_LINK];
if (!(ncm->data[2] & 0x1))
netdev_info(ndp->ndev.dev,
"NCSI: Channel %u forced, but it is link down\n",
found->id);
goto out;
}

/* The search is done once an inactive channel with up
* link is found.
*/
found = NULL;
NCSI_FOR_EACH_PACKAGE(ndp, np) {
if (ndp->force_package && np != ndp->force_package)
continue;
NCSI_FOR_EACH_CHANNEL(np, nc) {
spin_lock_irqsave(&nc->lock, flags);

Expand Down Expand Up @@ -1594,6 +1611,9 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
ndp->ptype.dev = dev;
dev_add_pack(&ndp->ptype);

/* Set up generic netlink interface */
ncsi_init_netlink(dev);

return nd;
}
EXPORT_SYMBOL_GPL(ncsi_register_dev);
Expand Down Expand Up @@ -1673,6 +1693,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
#endif
spin_unlock_irqrestore(&ncsi_dev_lock, flags);

ncsi_unregister_netlink(nd->dev);

kfree(ndp);
}
EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
Loading

0 comments on commit 955dc68

Please sign in to comment.