Skip to content

Commit 832629c

Browse files
Richard Alpedavem330
authored andcommitted
tipc: add UDP remoteip dump to netlink API
When using replicast a UDP bearer can have an arbitrary amount of remote ip addresses associated with it. This means we cannot simply add all remote ip addresses to an existing bearer data message as it might fill the message, leaving us with a truncated message that we can't safely resume. To handle this we introduce the new netlink command TIPC_NL_UDP_GET_REMOTEIP. This command is intended to be called when the bearer data message has the TIPC_NLA_UDP_MULTI_REMOTEIP flag set, indicating there are more than one remote ip (replicast). Signed-off-by: Richard Alpe <[email protected]> Reviewed-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fdb3acc commit 832629c

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

net/tipc/netlink.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "link.h"
4242
#include "node.h"
4343
#include "net.h"
44+
#include "udp_media.h"
4445
#include <net/genetlink.h>
4546

4647
static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
@@ -247,7 +248,14 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
247248
.cmd = TIPC_NL_PEER_REMOVE,
248249
.doit = tipc_nl_peer_rm,
249250
.policy = tipc_nl_policy,
250-
}
251+
},
252+
#ifdef CONFIG_TIPC_MEDIA_UDP
253+
{
254+
.cmd = TIPC_NL_UDP_GET_REMOTEIP,
255+
.dumpit = tipc_udp_nl_dump_remoteip,
256+
.policy = tipc_nl_policy,
257+
},
258+
#endif
251259
};
252260

253261
int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)

net/tipc/udp_media.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,96 @@ static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
428428
return 0;
429429
}
430430

431+
int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
432+
{
433+
u32 bid = cb->args[0];
434+
u32 skip_cnt = cb->args[1];
435+
u32 portid = NETLINK_CB(cb->skb).portid;
436+
struct udp_replicast *rcast, *tmp;
437+
struct tipc_bearer *b;
438+
struct udp_bearer *ub;
439+
void *hdr;
440+
int err;
441+
int i;
442+
443+
if (!bid && !skip_cnt) {
444+
struct net *net = sock_net(skb->sk);
445+
struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
446+
struct nlattr **attrs;
447+
char *bname;
448+
449+
err = tipc_nlmsg_parse(cb->nlh, &attrs);
450+
if (err)
451+
return err;
452+
453+
if (!attrs[TIPC_NLA_BEARER])
454+
return -EINVAL;
455+
456+
err = nla_parse_nested(battrs, TIPC_NLA_BEARER_MAX,
457+
attrs[TIPC_NLA_BEARER],
458+
tipc_nl_bearer_policy);
459+
if (err)
460+
return err;
461+
462+
if (!battrs[TIPC_NLA_BEARER_NAME])
463+
return -EINVAL;
464+
465+
bname = nla_data(battrs[TIPC_NLA_BEARER_NAME]);
466+
467+
rtnl_lock();
468+
b = tipc_bearer_find(net, bname);
469+
if (!b) {
470+
rtnl_unlock();
471+
return -EINVAL;
472+
}
473+
bid = b->identity;
474+
} else {
475+
struct net *net = sock_net(skb->sk);
476+
struct tipc_net *tn = net_generic(net, tipc_net_id);
477+
478+
rtnl_lock();
479+
b = rtnl_dereference(tn->bearer_list[bid]);
480+
if (!b) {
481+
rtnl_unlock();
482+
return -EINVAL;
483+
}
484+
}
485+
486+
ub = rcu_dereference_rtnl(b->media_ptr);
487+
if (!ub) {
488+
rtnl_unlock();
489+
return -EINVAL;
490+
}
491+
492+
i = 0;
493+
list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
494+
if (i < skip_cnt)
495+
goto count;
496+
497+
hdr = genlmsg_put(skb, portid, cb->nlh->nlmsg_seq,
498+
&tipc_genl_family, NLM_F_MULTI,
499+
TIPC_NL_BEARER_GET);
500+
if (!hdr)
501+
goto done;
502+
503+
err = __tipc_nl_add_udp_addr(skb, &rcast->addr,
504+
TIPC_NLA_UDP_REMOTE);
505+
if (err) {
506+
genlmsg_cancel(skb, hdr);
507+
goto done;
508+
}
509+
genlmsg_end(skb, hdr);
510+
count:
511+
i++;
512+
}
513+
done:
514+
rtnl_unlock();
515+
cb->args[0] = bid;
516+
cb->args[1] = i;
517+
518+
return skb->len;
519+
}
520+
431521
int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
432522
{
433523
struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;

net/tipc/udp_media.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr);
4242
int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b);
43+
int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb);
4344

4445
#endif
4546
#endif

0 commit comments

Comments
 (0)