Merge branch 'tipc-next'
Erik Hugne says: ==================== tipc: add support for link state subscriptions Low level topology information like TIPC link up/down is useful for applications like teamd to make smarter failover decisions in a HA cluster environment. Fetching logical link names through an ioctl may hurt the eyes of some. Suggestions for a more elegant way of doing this would be appreciated in that case. :) v2: -Properly based on net-next -Off-list comments from Billie Alsup: -Add a string length parameter to tipc_node_get_linkname -Use TIPC_MAX_LINK_NAME definition instead of hardcoded value in tipc_sioc_ln_req linkname ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
7f51531c11
|
@ -38,6 +38,7 @@
|
|||
#define _LINUX_TIPC_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
/*
|
||||
* TIPC addressing primitives
|
||||
|
@ -87,6 +88,7 @@ static inline unsigned int tipc_node(__u32 addr)
|
|||
|
||||
#define TIPC_CFG_SRV 0 /* configuration service name type */
|
||||
#define TIPC_TOP_SRV 1 /* topology service name type */
|
||||
#define TIPC_LINK_STATE 2 /* link state name type */
|
||||
#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */
|
||||
|
||||
/*
|
||||
|
@ -206,4 +208,25 @@ struct sockaddr_tipc {
|
|||
#define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */
|
||||
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
|
||||
|
||||
/*
|
||||
* Maximum sizes of TIPC bearer-related names (including terminating NULL)
|
||||
* The string formatting for each name element is:
|
||||
* media: media
|
||||
* interface: media:interface name
|
||||
* link: Z.C.N:interface-Z.C.N:interface
|
||||
*
|
||||
*/
|
||||
|
||||
#define TIPC_MAX_MEDIA_NAME 16
|
||||
#define TIPC_MAX_IF_NAME 16
|
||||
#define TIPC_MAX_BEARER_NAME 32
|
||||
#define TIPC_MAX_LINK_NAME 60
|
||||
|
||||
#define SIOCGETLINKNAME SIOCPROTOPRIVATE
|
||||
|
||||
struct tipc_sioc_ln_req {
|
||||
__u32 peer;
|
||||
__u32 bearer_id;
|
||||
char linkname[TIPC_MAX_LINK_NAME];
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/tipc.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
@ -154,15 +155,6 @@
|
|||
#define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */
|
||||
#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */
|
||||
|
||||
/*
|
||||
* Maximum sizes of TIPC bearer-related names (including terminating NUL)
|
||||
*/
|
||||
|
||||
#define TIPC_MAX_MEDIA_NAME 16 /* format = media */
|
||||
#define TIPC_MAX_IF_NAME 16 /* format = interface */
|
||||
#define TIPC_MAX_BEARER_NAME 32 /* format = media:interface */
|
||||
#define TIPC_MAX_LINK_NAME 60 /* format = Z.C.N:interface-Z.C.N:interface */
|
||||
|
||||
/*
|
||||
* Link priority limits (min, default, max, media default)
|
||||
*/
|
||||
|
|
|
@ -144,9 +144,11 @@ void tipc_node_stop(void)
|
|||
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
|
||||
{
|
||||
struct tipc_link **active = &n_ptr->active_links[0];
|
||||
u32 addr = n_ptr->addr;
|
||||
|
||||
n_ptr->working_links++;
|
||||
|
||||
tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE,
|
||||
l_ptr->bearer_id, addr);
|
||||
pr_info("Established link <%s> on network plane %c\n",
|
||||
l_ptr->name, l_ptr->net_plane);
|
||||
|
||||
|
@ -203,8 +205,10 @@ static void node_select_active_links(struct tipc_node *n_ptr)
|
|||
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
|
||||
{
|
||||
struct tipc_link **active;
|
||||
u32 addr = n_ptr->addr;
|
||||
|
||||
n_ptr->working_links--;
|
||||
tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr);
|
||||
|
||||
if (!tipc_link_is_active(l_ptr)) {
|
||||
pr_info("Lost standby link <%s> on network plane %c\n",
|
||||
|
@ -434,3 +438,30 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
|
|||
rcu_read_unlock();
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* tipc_node_get_linkname - get the name of a link
|
||||
*
|
||||
* @bearer_id: id of the bearer
|
||||
* @node: peer node address
|
||||
* @linkname: link name output buffer
|
||||
*
|
||||
* Returns 0 on success
|
||||
*/
|
||||
int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
|
||||
{
|
||||
struct tipc_link *link;
|
||||
struct tipc_node *node = tipc_node_find(addr);
|
||||
|
||||
if ((bearer_id > MAX_BEARERS) || !node)
|
||||
return -EINVAL;
|
||||
tipc_node_lock(node);
|
||||
link = node->links[bearer_id];
|
||||
if (link) {
|
||||
strncpy(linkname, link->name, len);
|
||||
tipc_node_unlock(node);
|
||||
return 0;
|
||||
}
|
||||
tipc_node_unlock(node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ int tipc_node_active_links(struct tipc_node *n_ptr);
|
|||
int tipc_node_is_up(struct tipc_node *n_ptr);
|
||||
struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
|
||||
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
|
||||
int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
|
||||
|
||||
static inline void tipc_node_lock(struct tipc_node *n_ptr)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "core.h"
|
||||
#include "port.h"
|
||||
#include "node.h"
|
||||
|
||||
#include <linux/export.h>
|
||||
|
||||
|
@ -1905,6 +1906,28 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
|
|||
return put_user(sizeof(value), ol);
|
||||
}
|
||||
|
||||
int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct tipc_sioc_ln_req lnr;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGETLINKNAME:
|
||||
if (copy_from_user(&lnr, argp, sizeof(lnr)))
|
||||
return -EFAULT;
|
||||
if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer,
|
||||
lnr.linkname, TIPC_MAX_LINK_NAME)) {
|
||||
if (copy_to_user(argp, &lnr, sizeof(lnr)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
return -EADDRNOTAVAIL;
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Protocol switches for the various types of TIPC sockets */
|
||||
|
||||
static const struct proto_ops msg_ops = {
|
||||
|
@ -1917,7 +1940,7 @@ static const struct proto_ops msg_ops = {
|
|||
.accept = sock_no_accept,
|
||||
.getname = tipc_getname,
|
||||
.poll = tipc_poll,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.ioctl = tipc_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = tipc_shutdown,
|
||||
.setsockopt = tipc_setsockopt,
|
||||
|
@ -1938,7 +1961,7 @@ static const struct proto_ops packet_ops = {
|
|||
.accept = tipc_accept,
|
||||
.getname = tipc_getname,
|
||||
.poll = tipc_poll,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.ioctl = tipc_ioctl,
|
||||
.listen = tipc_listen,
|
||||
.shutdown = tipc_shutdown,
|
||||
.setsockopt = tipc_setsockopt,
|
||||
|
@ -1959,7 +1982,7 @@ static const struct proto_ops stream_ops = {
|
|||
.accept = tipc_accept,
|
||||
.getname = tipc_getname,
|
||||
.poll = tipc_poll,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.ioctl = tipc_ioctl,
|
||||
.listen = tipc_listen,
|
||||
.shutdown = tipc_shutdown,
|
||||
.setsockopt = tipc_setsockopt,
|
||||
|
|
Loading…
Reference in a new issue