As a further preparation for the upcoming 'replicast' functionality, we add some necessary structs and functions for looking up and returning a list of all nodes that host destinations for a given multicast message.
Signed-off-by: Jon Maloy <jon.ma...@ericsson.com> --- net/tipc/name_table.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ net/tipc/name_table.h | 24 +++++++++++++ 2 files changed, 119 insertions(+) diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index e190460..cb9c7ea 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -645,6 +645,42 @@ exit: return res; } +/* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes + * - Creates list of nodes that overlap the given multicast address + * - Determines if any node local ports overlap + */ +void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, + u32 upper, u32 domain, + struct tipc_nlist *nodes) +{ + struct sub_seq *sseq, *stop; + struct publication *publ; + struct name_info *info; + struct name_seq *seq; + u32 self = tipc_own_addr(net); + + rcu_read_lock(); + seq = nametbl_find_seq(net, type); + if (!seq) + goto exit; + + spin_lock_bh(&seq->lock); + sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); + stop = seq->sseqs + seq->first_free; + for (; sseq->lower <= upper && sseq != stop; sseq++) { + info = sseq->info; + list_for_each_entry(publ, &info->zone_list, zone_list) { + if (publ->node == self) + nodes->local = true; + else if (tipc_in_scope(domain, publ->node)) + tipc_nlist_add(nodes, publ->node); + } + } + spin_unlock_bh(&seq->lock); +exit: + rcu_read_unlock(); +} + /* * tipc_nametbl_publish - add name publication to network name tables */ @@ -1059,3 +1095,62 @@ u32 tipc_plist_pop(struct tipc_plist *pl) kfree(nl); return port; } + +void tipc_nlist_init(struct tipc_nlist *nl) +{ + memset(nl, 0, sizeof(*nl)); + INIT_LIST_HEAD(&nl->sent); + INIT_LIST_HEAD(&nl->unsent); + skb_queue_head_init(&nl->localq); +} + +void tipc_nlist_add(struct tipc_nlist *nl, u32 node) +{ + struct tipc_nitem *n, *tmp; + + list_for_each_entry_safe(n, tmp, &nl->unsent, list) { + if (n->node == node) + return; + } + n = kzalloc(sizeof(*n), GFP_KERNEL); + if (!n) + return; + n->node = node; + nl->remote++; + list_add(&n->list, &nl->unsent); +} + +void tipc_nlist_sent(struct tipc_nlist *nl, struct tipc_nitem *n) +{ + list_del(&n->list); + list_add(&n->list, &nl->sent); + nl->remote--; +} + +void tipc_nlist_del(struct tipc_nlist *nl, struct tipc_nitem *n) +{ + list_del(&n->list); + kfree(n); + nl->remote--; +} + +void tipc_nlist_restore(struct tipc_nlist *nl) +{ + list_splice_tail_init(&nl->sent, &nl->unsent); + nl->remote = 0; + nl->local = 0; +} + +void tipc_nlist_purge(struct tipc_nlist *nl) +{ + struct tipc_nitem *n, *tmp; + + list_for_each_entry_safe(n, tmp, &nl->unsent, list) { + list_del(&n->list); + kfree(n); + } + list_for_each_entry_safe(n, tmp, &nl->sent, list) { + list_del(&n->list); + kfree(n); + } +} diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index 1524a73..d1061b6 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h @@ -39,6 +39,7 @@ struct tipc_subscription; struct tipc_plist; +struct tipc_nlist; /* * TIPC name types reserved for internal TIPC use (both current and planned) @@ -100,6 +101,9 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, u32 limit, struct tipc_plist *dports); +void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, + u32 upper, u32 domain, + struct tipc_nlist *nodes); struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, u32 upper, u32 scope, u32 port_ref, u32 key); @@ -130,4 +134,24 @@ static inline void tipc_plist_init(struct tipc_plist *pl) void tipc_plist_push(struct tipc_plist *pl, u32 port); u32 tipc_plist_pop(struct tipc_plist *pl); +struct tipc_nitem { + struct list_head list; + u32 node; +}; + +struct tipc_nlist { + struct list_head unsent; + struct list_head sent; + struct sk_buff_head localq; + int remote; + bool local; +}; + +void tipc_nlist_init(struct tipc_nlist *nl); +void tipc_nlist_restore(struct tipc_nlist *nl); +void tipc_nlist_purge(struct tipc_nlist *nl); +void tipc_nlist_add(struct tipc_nlist *nl, u32 node); +void tipc_nlist_sent(struct tipc_nlist *nl, struct tipc_nitem *n); +void tipc_nlist_del(struct tipc_nlist *nl, struct tipc_nitem *n); + #endif -- 2.7.4 ------------------------------------------------------------------------------ _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion