Skip to content

Commit 7f51531

Browse files
committed
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 <[email protected]>
2 parents d42f157 + 78acb1f commit 7f51531

File tree

5 files changed

+83
-13
lines changed

5 files changed

+83
-13
lines changed

include/uapi/linux/tipc.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define _LINUX_TIPC_H_
3939

4040
#include <linux/types.h>
41+
#include <linux/sockios.h>
4142

4243
/*
4344
* TIPC addressing primitives
@@ -87,6 +88,7 @@ static inline unsigned int tipc_node(__u32 addr)
8788

8889
#define TIPC_CFG_SRV 0 /* configuration service name type */
8990
#define TIPC_TOP_SRV 1 /* topology service name type */
91+
#define TIPC_LINK_STATE 2 /* link state name type */
9092
#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */
9193

9294
/*
@@ -206,4 +208,25 @@ struct sockaddr_tipc {
206208
#define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */
207209
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
208210

211+
/*
212+
* Maximum sizes of TIPC bearer-related names (including terminating NULL)
213+
* The string formatting for each name element is:
214+
* media: media
215+
* interface: media:interface name
216+
* link: Z.C.N:interface-Z.C.N:interface
217+
*
218+
*/
219+
220+
#define TIPC_MAX_MEDIA_NAME 16
221+
#define TIPC_MAX_IF_NAME 16
222+
#define TIPC_MAX_BEARER_NAME 32
223+
#define TIPC_MAX_LINK_NAME 60
224+
225+
#define SIOCGETLINKNAME SIOCPROTOPRIVATE
226+
227+
struct tipc_sioc_ln_req {
228+
__u32 peer;
229+
__u32 bearer_id;
230+
char linkname[TIPC_MAX_LINK_NAME];
231+
};
209232
#endif

include/uapi/linux/tipc_config.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
#include <linux/types.h>
4141
#include <linux/string.h>
42+
#include <linux/tipc.h>
4243
#include <asm/byteorder.h>
4344

4445
#ifndef __KERNEL__
@@ -154,15 +155,6 @@
154155
#define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */
155156
#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */
156157

157-
/*
158-
* Maximum sizes of TIPC bearer-related names (including terminating NUL)
159-
*/
160-
161-
#define TIPC_MAX_MEDIA_NAME 16 /* format = media */
162-
#define TIPC_MAX_IF_NAME 16 /* format = interface */
163-
#define TIPC_MAX_BEARER_NAME 32 /* format = media:interface */
164-
#define TIPC_MAX_LINK_NAME 60 /* format = Z.C.N:interface-Z.C.N:interface */
165-
166158
/*
167159
* Link priority limits (min, default, max, media default)
168160
*/

net/tipc/node.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,11 @@ void tipc_node_stop(void)
144144
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
145145
{
146146
struct tipc_link **active = &n_ptr->active_links[0];
147+
u32 addr = n_ptr->addr;
147148

148149
n_ptr->working_links++;
149-
150+
tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE,
151+
l_ptr->bearer_id, addr);
150152
pr_info("Established link <%s> on network plane %c\n",
151153
l_ptr->name, l_ptr->net_plane);
152154

@@ -203,8 +205,10 @@ static void node_select_active_links(struct tipc_node *n_ptr)
203205
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
204206
{
205207
struct tipc_link **active;
208+
u32 addr = n_ptr->addr;
206209

207210
n_ptr->working_links--;
211+
tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr);
208212

209213
if (!tipc_link_is_active(l_ptr)) {
210214
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)
434438
rcu_read_unlock();
435439
return buf;
436440
}
441+
442+
/**
443+
* tipc_node_get_linkname - get the name of a link
444+
*
445+
* @bearer_id: id of the bearer
446+
* @node: peer node address
447+
* @linkname: link name output buffer
448+
*
449+
* Returns 0 on success
450+
*/
451+
int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
452+
{
453+
struct tipc_link *link;
454+
struct tipc_node *node = tipc_node_find(addr);
455+
456+
if ((bearer_id > MAX_BEARERS) || !node)
457+
return -EINVAL;
458+
tipc_node_lock(node);
459+
link = node->links[bearer_id];
460+
if (link) {
461+
strncpy(linkname, link->name, len);
462+
tipc_node_unlock(node);
463+
return 0;
464+
}
465+
tipc_node_unlock(node);
466+
return -EINVAL;
467+
}

net/tipc/node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ int tipc_node_active_links(struct tipc_node *n_ptr);
118118
int tipc_node_is_up(struct tipc_node *n_ptr);
119119
struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
120120
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
121+
int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
121122

122123
static inline void tipc_node_lock(struct tipc_node *n_ptr)
123124
{

net/tipc/socket.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include "core.h"
3838
#include "port.h"
39+
#include "node.h"
3940

4041
#include <linux/export.h>
4142

@@ -1905,6 +1906,28 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
19051906
return put_user(sizeof(value), ol);
19061907
}
19071908

1909+
int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
1910+
{
1911+
struct tipc_sioc_ln_req lnr;
1912+
void __user *argp = (void __user *)arg;
1913+
1914+
switch (cmd) {
1915+
case SIOCGETLINKNAME:
1916+
if (copy_from_user(&lnr, argp, sizeof(lnr)))
1917+
return -EFAULT;
1918+
if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer,
1919+
lnr.linkname, TIPC_MAX_LINK_NAME)) {
1920+
if (copy_to_user(argp, &lnr, sizeof(lnr)))
1921+
return -EFAULT;
1922+
return 0;
1923+
}
1924+
return -EADDRNOTAVAIL;
1925+
break;
1926+
default:
1927+
return -ENOIOCTLCMD;
1928+
}
1929+
}
1930+
19081931
/* Protocol switches for the various types of TIPC sockets */
19091932

19101933
static const struct proto_ops msg_ops = {
@@ -1917,7 +1940,7 @@ static const struct proto_ops msg_ops = {
19171940
.accept = sock_no_accept,
19181941
.getname = tipc_getname,
19191942
.poll = tipc_poll,
1920-
.ioctl = sock_no_ioctl,
1943+
.ioctl = tipc_ioctl,
19211944
.listen = sock_no_listen,
19221945
.shutdown = tipc_shutdown,
19231946
.setsockopt = tipc_setsockopt,
@@ -1938,7 +1961,7 @@ static const struct proto_ops packet_ops = {
19381961
.accept = tipc_accept,
19391962
.getname = tipc_getname,
19401963
.poll = tipc_poll,
1941-
.ioctl = sock_no_ioctl,
1964+
.ioctl = tipc_ioctl,
19421965
.listen = tipc_listen,
19431966
.shutdown = tipc_shutdown,
19441967
.setsockopt = tipc_setsockopt,
@@ -1959,7 +1982,7 @@ static const struct proto_ops stream_ops = {
19591982
.accept = tipc_accept,
19601983
.getname = tipc_getname,
19611984
.poll = tipc_poll,
1962-
.ioctl = sock_no_ioctl,
1985+
.ioctl = tipc_ioctl,
19631986
.listen = tipc_listen,
19641987
.shutdown = tipc_shutdown,
19651988
.setsockopt = tipc_setsockopt,

0 commit comments

Comments
 (0)