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

Reply via email to