tipc: add the ability to get UDP options via netlink
Add UDP bearer options to netlink bearer get message. This is used by the tipc user space tool to display UDP options. The UDP bearer information is passed using either a sockaddr_in or sockaddr_in6 structs. This means the user space receiver should intermediately store the retrieved data in a large enough struct (sockaddr_strage) before casting to the proper IP version type. Signed-off-by: Richard Alpe <richard.alpe@ericsson.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c9b64d492b
Коммит
fdb3accc2c
|
@ -61,6 +61,7 @@ enum {
|
||||||
TIPC_NL_MON_PEER_GET,
|
TIPC_NL_MON_PEER_GET,
|
||||||
TIPC_NL_PEER_REMOVE,
|
TIPC_NL_PEER_REMOVE,
|
||||||
TIPC_NL_BEARER_ADD,
|
TIPC_NL_BEARER_ADD,
|
||||||
|
TIPC_NL_UDP_GET_REMOTEIP,
|
||||||
|
|
||||||
__TIPC_NL_CMD_MAX,
|
__TIPC_NL_CMD_MAX,
|
||||||
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
|
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
|
||||||
|
@ -100,6 +101,7 @@ enum {
|
||||||
TIPC_NLA_UDP_UNSPEC,
|
TIPC_NLA_UDP_UNSPEC,
|
||||||
TIPC_NLA_UDP_LOCAL, /* sockaddr_storage */
|
TIPC_NLA_UDP_LOCAL, /* sockaddr_storage */
|
||||||
TIPC_NLA_UDP_REMOTE, /* sockaddr_storage */
|
TIPC_NLA_UDP_REMOTE, /* sockaddr_storage */
|
||||||
|
TIPC_NLA_UDP_MULTI_REMOTEIP, /* flag */
|
||||||
|
|
||||||
__TIPC_NLA_UDP_MAX,
|
__TIPC_NLA_UDP_MAX,
|
||||||
TIPC_NLA_UDP_MAX = __TIPC_NLA_UDP_MAX - 1
|
TIPC_NLA_UDP_MAX = __TIPC_NLA_UDP_MAX - 1
|
||||||
|
|
|
@ -712,6 +712,14 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
|
||||||
goto prop_msg_full;
|
goto prop_msg_full;
|
||||||
|
|
||||||
nla_nest_end(msg->skb, prop);
|
nla_nest_end(msg->skb, prop);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TIPC_MEDIA_UDP
|
||||||
|
if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP) {
|
||||||
|
if (tipc_udp_nl_add_bearer_data(msg, bearer))
|
||||||
|
goto attr_msg_full;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
nla_nest_end(msg->skb, attrs);
|
nla_nest_end(msg->skb, attrs);
|
||||||
genlmsg_end(msg->skb, hdr);
|
genlmsg_end(msg->skb, hdr);
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,67 @@ static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
|
||||||
|
struct udp_media_addr *addr, int nla_t)
|
||||||
|
{
|
||||||
|
if (ntohs(addr->proto) == ETH_P_IP) {
|
||||||
|
struct sockaddr_in ip4;
|
||||||
|
|
||||||
|
ip4.sin_family = AF_INET;
|
||||||
|
ip4.sin_port = addr->port;
|
||||||
|
ip4.sin_addr.s_addr = addr->ipv4.s_addr;
|
||||||
|
if (nla_put(skb, nla_t, sizeof(ip4), &ip4))
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_IPV6)
|
||||||
|
} else if (ntohs(addr->proto) == ETH_P_IPV6) {
|
||||||
|
struct sockaddr_in6 ip6;
|
||||||
|
|
||||||
|
ip6.sin6_family = AF_INET6;
|
||||||
|
ip6.sin6_port = addr->port;
|
||||||
|
memcpy(&ip6.sin6_addr, &addr->ipv6, sizeof(struct in6_addr));
|
||||||
|
if (nla_put(skb, nla_t, sizeof(ip6), &ip6))
|
||||||
|
return -EMSGSIZE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
|
||||||
|
{
|
||||||
|
struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
|
||||||
|
struct udp_media_addr *dst;
|
||||||
|
struct udp_bearer *ub;
|
||||||
|
struct nlattr *nest;
|
||||||
|
|
||||||
|
ub = rcu_dereference_rtnl(b->media_ptr);
|
||||||
|
if (!ub)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
nest = nla_nest_start(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
|
||||||
|
if (!nest)
|
||||||
|
goto msg_full;
|
||||||
|
|
||||||
|
if (__tipc_nl_add_udp_addr(msg->skb, src, TIPC_NLA_UDP_LOCAL))
|
||||||
|
goto msg_full;
|
||||||
|
|
||||||
|
dst = (struct udp_media_addr *)&b->bcast_addr.value;
|
||||||
|
if (__tipc_nl_add_udp_addr(msg->skb, dst, TIPC_NLA_UDP_REMOTE))
|
||||||
|
goto msg_full;
|
||||||
|
|
||||||
|
if (!list_empty(&ub->rcast.list)) {
|
||||||
|
if (nla_put_flag(msg->skb, TIPC_NLA_UDP_MULTI_REMOTEIP))
|
||||||
|
goto msg_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(msg->skb, nest);
|
||||||
|
return 0;
|
||||||
|
msg_full:
|
||||||
|
nla_nest_cancel(msg->skb, nest);
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tipc_parse_udp_addr - build udp media address from netlink data
|
* tipc_parse_udp_addr - build udp media address from netlink data
|
||||||
* @nlattr: netlink attribute containing sockaddr storage aligned address
|
* @nlattr: netlink attribute containing sockaddr storage aligned address
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#define _TIPC_UDP_MEDIA_H
|
#define _TIPC_UDP_MEDIA_H
|
||||||
|
|
||||||
int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr);
|
int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr);
|
||||||
|
int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче