Commit 78acb1f9 authored by Erik Hugne's avatar Erik Hugne Committed by David S. Miller

tipc: add ioctl to fetch link names

We add a new ioctl for AF_TIPC that can be used to fetch the
logical name for a link to a remote node on a given bearer. This
should be used in combination with link state subscriptions.
The logical name size limit definitions are moved to tipc.h, as
they are now also needed by the new ioctl.
Signed-off-by: default avatarErik Hugne <erik.hugne@ericsson.com>
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Reviewed-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a89778d8
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define _LINUX_TIPC_H_ #define _LINUX_TIPC_H_
#include <linux/types.h> #include <linux/types.h>
#include <linux/sockios.h>
/* /*
* TIPC addressing primitives * TIPC addressing primitives
...@@ -207,4 +208,25 @@ struct sockaddr_tipc { ...@@ -207,4 +208,25 @@ struct sockaddr_tipc {
#define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */ #define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */
#define TIPC_SOCK_RECVQ_DEPTH 132 /* 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 #endif
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/tipc.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifndef __KERNEL__ #ifndef __KERNEL__
...@@ -154,15 +155,6 @@ ...@@ -154,15 +155,6 @@
#define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */ #define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */
#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */ #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) * Link priority limits (min, default, max, media default)
*/ */
......
...@@ -438,3 +438,30 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) ...@@ -438,3 +438,30 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
rcu_read_unlock(); rcu_read_unlock();
return buf; 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); ...@@ -118,6 +118,7 @@ int tipc_node_active_links(struct tipc_node *n_ptr);
int tipc_node_is_up(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_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); 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) static inline void tipc_node_lock(struct tipc_node *n_ptr)
{ {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "core.h" #include "core.h"
#include "port.h" #include "port.h"
#include "node.h"
#include <linux/export.h> #include <linux/export.h>
...@@ -1905,6 +1906,28 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, ...@@ -1905,6 +1906,28 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
return put_user(sizeof(value), ol); 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 */ /* Protocol switches for the various types of TIPC sockets */
static const struct proto_ops msg_ops = { static const struct proto_ops msg_ops = {
...@@ -1917,7 +1940,7 @@ static const struct proto_ops msg_ops = { ...@@ -1917,7 +1940,7 @@ static const struct proto_ops msg_ops = {
.accept = sock_no_accept, .accept = sock_no_accept,
.getname = tipc_getname, .getname = tipc_getname,
.poll = tipc_poll, .poll = tipc_poll,
.ioctl = sock_no_ioctl, .ioctl = tipc_ioctl,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = tipc_shutdown, .shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt, .setsockopt = tipc_setsockopt,
...@@ -1938,7 +1961,7 @@ static const struct proto_ops packet_ops = { ...@@ -1938,7 +1961,7 @@ static const struct proto_ops packet_ops = {
.accept = tipc_accept, .accept = tipc_accept,
.getname = tipc_getname, .getname = tipc_getname,
.poll = tipc_poll, .poll = tipc_poll,
.ioctl = sock_no_ioctl, .ioctl = tipc_ioctl,
.listen = tipc_listen, .listen = tipc_listen,
.shutdown = tipc_shutdown, .shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt, .setsockopt = tipc_setsockopt,
...@@ -1959,7 +1982,7 @@ static const struct proto_ops stream_ops = { ...@@ -1959,7 +1982,7 @@ static const struct proto_ops stream_ops = {
.accept = tipc_accept, .accept = tipc_accept,
.getname = tipc_getname, .getname = tipc_getname,
.poll = tipc_poll, .poll = tipc_poll,
.ioctl = sock_no_ioctl, .ioctl = tipc_ioctl,
.listen = tipc_listen, .listen = tipc_listen,
.shutdown = tipc_shutdown, .shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt, .setsockopt = tipc_setsockopt,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment