Skip to content

Commit 955dc68

Browse files
sammjdavem330
authored andcommitted
net/ncsi: Add generic netlink family
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent be63189 commit 955dc68

File tree

6 files changed

+586
-5
lines changed

6 files changed

+586
-5
lines changed

include/uapi/linux/ncsi.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*/
9+
10+
#ifndef __UAPI_NCSI_NETLINK_H__
11+
#define __UAPI_NCSI_NETLINK_H__
12+
13+
/**
14+
* enum ncsi_nl_commands - supported NCSI commands
15+
*
16+
* @NCSI_CMD_UNSPEC: unspecified command to catch errors
17+
* @NCSI_CMD_PKG_INFO: list package and channel attributes. Requires
18+
* NCSI_ATTR_IFINDEX. If NCSI_ATTR_PACKAGE_ID is specified returns the
19+
* specific package and its channels - otherwise a dump request returns
20+
* all packages and their associated channels.
21+
* @NCSI_CMD_SET_INTERFACE: set preferred package and channel combination.
22+
* Requires NCSI_ATTR_IFINDEX and the preferred NCSI_ATTR_PACKAGE_ID and
23+
* optionally the preferred NCSI_ATTR_CHANNEL_ID.
24+
* @NCSI_CMD_CLEAR_INTERFACE: clear any preferred package/channel combination.
25+
* Requires NCSI_ATTR_IFINDEX.
26+
* @NCSI_CMD_MAX: highest command number
27+
*/
28+
enum ncsi_nl_commands {
29+
NCSI_CMD_UNSPEC,
30+
NCSI_CMD_PKG_INFO,
31+
NCSI_CMD_SET_INTERFACE,
32+
NCSI_CMD_CLEAR_INTERFACE,
33+
34+
__NCSI_CMD_AFTER_LAST,
35+
NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
36+
};
37+
38+
/**
39+
* enum ncsi_nl_attrs - General NCSI netlink attributes
40+
*
41+
* @NCSI_ATTR_UNSPEC: unspecified attributes to catch errors
42+
* @NCSI_ATTR_IFINDEX: ifindex of network device using NCSI
43+
* @NCSI_ATTR_PACKAGE_LIST: nested array of NCSI_PKG_ATTR attributes
44+
* @NCSI_ATTR_PACKAGE_ID: package ID
45+
* @NCSI_ATTR_CHANNEL_ID: channel ID
46+
* @NCSI_ATTR_MAX: highest attribute number
47+
*/
48+
enum ncsi_nl_attrs {
49+
NCSI_ATTR_UNSPEC,
50+
NCSI_ATTR_IFINDEX,
51+
NCSI_ATTR_PACKAGE_LIST,
52+
NCSI_ATTR_PACKAGE_ID,
53+
NCSI_ATTR_CHANNEL_ID,
54+
55+
__NCSI_ATTR_AFTER_LAST,
56+
NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
57+
};
58+
59+
/**
60+
* enum ncsi_nl_pkg_attrs - NCSI netlink package-specific attributes
61+
*
62+
* @NCSI_PKG_ATTR_UNSPEC: unspecified attributes to catch errors
63+
* @NCSI_PKG_ATTR: nested array of package attributes
64+
* @NCSI_PKG_ATTR_ID: package ID
65+
* @NCSI_PKG_ATTR_FORCED: flag signifying a package has been set as preferred
66+
* @NCSI_PKG_ATTR_CHANNEL_LIST: nested array of NCSI_CHANNEL_ATTR attributes
67+
* @NCSI_PKG_ATTR_MAX: highest attribute number
68+
*/
69+
enum ncsi_nl_pkg_attrs {
70+
NCSI_PKG_ATTR_UNSPEC,
71+
NCSI_PKG_ATTR,
72+
NCSI_PKG_ATTR_ID,
73+
NCSI_PKG_ATTR_FORCED,
74+
NCSI_PKG_ATTR_CHANNEL_LIST,
75+
76+
__NCSI_PKG_ATTR_AFTER_LAST,
77+
NCSI_PKG_ATTR_MAX = __NCSI_PKG_ATTR_AFTER_LAST - 1
78+
};
79+
80+
/**
81+
* enum ncsi_nl_channel_attrs - NCSI netlink channel-specific attributes
82+
*
83+
* @NCSI_CHANNEL_ATTR_UNSPEC: unspecified attributes to catch errors
84+
* @NCSI_CHANNEL_ATTR: nested array of channel attributes
85+
* @NCSI_CHANNEL_ATTR_ID: channel ID
86+
* @NCSI_CHANNEL_ATTR_VERSION_MAJOR: channel major version number
87+
* @NCSI_CHANNEL_ATTR_VERSION_MINOR: channel minor version number
88+
* @NCSI_CHANNEL_ATTR_VERSION_STR: channel version string
89+
* @NCSI_CHANNEL_ATTR_LINK_STATE: channel link state flags
90+
* @NCSI_CHANNEL_ATTR_ACTIVE: channels with this flag are in
91+
* NCSI_CHANNEL_ACTIVE state
92+
* @NCSI_CHANNEL_ATTR_FORCED: flag signifying a channel has been set as
93+
* preferred
94+
* @NCSI_CHANNEL_ATTR_VLAN_LIST: nested array of NCSI_CHANNEL_ATTR_VLAN_IDs
95+
* @NCSI_CHANNEL_ATTR_VLAN_ID: VLAN ID being filtered on this channel
96+
* @NCSI_CHANNEL_ATTR_MAX: highest attribute number
97+
*/
98+
enum ncsi_nl_channel_attrs {
99+
NCSI_CHANNEL_ATTR_UNSPEC,
100+
NCSI_CHANNEL_ATTR,
101+
NCSI_CHANNEL_ATTR_ID,
102+
NCSI_CHANNEL_ATTR_VERSION_MAJOR,
103+
NCSI_CHANNEL_ATTR_VERSION_MINOR,
104+
NCSI_CHANNEL_ATTR_VERSION_STR,
105+
NCSI_CHANNEL_ATTR_LINK_STATE,
106+
NCSI_CHANNEL_ATTR_ACTIVE,
107+
NCSI_CHANNEL_ATTR_FORCED,
108+
NCSI_CHANNEL_ATTR_VLAN_LIST,
109+
NCSI_CHANNEL_ATTR_VLAN_ID,
110+
111+
__NCSI_CHANNEL_ATTR_AFTER_LAST,
112+
NCSI_CHANNEL_ATTR_MAX = __NCSI_CHANNEL_ATTR_AFTER_LAST - 1
113+
};
114+
115+
#endif /* __UAPI_NCSI_NETLINK_H__ */

net/ncsi/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#
22
# Makefile for NCSI API
33
#
4-
obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o
4+
obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o ncsi-netlink.o

net/ncsi/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ struct ncsi_dev_priv {
276276
unsigned int package_num; /* Number of packages */
277277
struct list_head packages; /* List of packages */
278278
struct ncsi_channel *hot_channel; /* Channel was ever active */
279+
struct ncsi_package *force_package; /* Force a specific package */
280+
struct ncsi_channel *force_channel; /* Force a specific channel */
279281
struct ncsi_request requests[256]; /* Request table */
280282
unsigned int request_id; /* Last used request ID */
281283
#define NCSI_REQ_START_IDX 1
@@ -318,6 +320,7 @@ extern spinlock_t ncsi_dev_lock;
318320
list_for_each_entry_rcu(nc, &np->channels, node)
319321

320322
/* Resources */
323+
u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index);
321324
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
322325
int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
323326
int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);

net/ncsi/ncsi-manage.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <linux/init.h>
1313
#include <linux/netdevice.h>
1414
#include <linux/skbuff.h>
15-
#include <linux/netlink.h>
1615

1716
#include <net/ncsi.h>
1817
#include <net/net_namespace.h>
@@ -23,6 +22,7 @@
2322

2423
#include "internal.h"
2524
#include "ncsi-pkt.h"
25+
#include "ncsi-netlink.h"
2626

2727
LIST_HEAD(ncsi_dev_list);
2828
DEFINE_SPINLOCK(ncsi_dev_lock);
@@ -38,7 +38,7 @@ static inline int ncsi_filter_size(int table)
3838
return sizes[table];
3939
}
4040

41-
static u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
41+
u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
4242
{
4343
struct ncsi_channel_filter *ncf;
4444
int size;
@@ -965,20 +965,37 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
965965

966966
static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
967967
{
968-
struct ncsi_package *np;
969-
struct ncsi_channel *nc, *found, *hot_nc;
968+
struct ncsi_package *np, *force_package;
969+
struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
970970
struct ncsi_channel_mode *ncm;
971971
unsigned long flags;
972972

973973
spin_lock_irqsave(&ndp->lock, flags);
974974
hot_nc = ndp->hot_channel;
975+
force_channel = ndp->force_channel;
976+
force_package = ndp->force_package;
975977
spin_unlock_irqrestore(&ndp->lock, flags);
976978

979+
/* Force a specific channel whether or not it has link if we have been
980+
* configured to do so
981+
*/
982+
if (force_package && force_channel) {
983+
found = force_channel;
984+
ncm = &found->modes[NCSI_MODE_LINK];
985+
if (!(ncm->data[2] & 0x1))
986+
netdev_info(ndp->ndev.dev,
987+
"NCSI: Channel %u forced, but it is link down\n",
988+
found->id);
989+
goto out;
990+
}
991+
977992
/* The search is done once an inactive channel with up
978993
* link is found.
979994
*/
980995
found = NULL;
981996
NCSI_FOR_EACH_PACKAGE(ndp, np) {
997+
if (ndp->force_package && np != ndp->force_package)
998+
continue;
982999
NCSI_FOR_EACH_CHANNEL(np, nc) {
9831000
spin_lock_irqsave(&nc->lock, flags);
9841001

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

1614+
/* Set up generic netlink interface */
1615+
ncsi_init_netlink(dev);
1616+
15971617
return nd;
15981618
}
15991619
EXPORT_SYMBOL_GPL(ncsi_register_dev);
@@ -1673,6 +1693,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
16731693
#endif
16741694
spin_unlock_irqrestore(&ncsi_dev_lock, flags);
16751695

1696+
ncsi_unregister_netlink(nd->dev);
1697+
16761698
kfree(ndp);
16771699
}
16781700
EXPORT_SYMBOL_GPL(ncsi_unregister_dev);

0 commit comments

Comments
 (0)