tipc: add functionality to lookup multicast destination nodes
authorJon Paul Maloy <jon.maloy@ericsson.com>
Wed, 18 Jan 2017 18:50:51 +0000 (13:50 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Jan 2017 17:10:16 +0000 (12:10 -0500)
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.

Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tipc/bcast.c
net/tipc/bcast.h
net/tipc/name_table.c
net/tipc/name_table.h

index 325627612bac0a69dd3ae73123b0c15b5fd610ad..412d3351abb79d98d1969e6e052ead16c33b0890 100644 (file)
@@ -39,9 +39,8 @@
 #include "socket.h"
 #include "msg.h"
 #include "bcast.h"
-#include "name_distr.h"
 #include "link.h"
-#include "node.h"
+#include "name_table.h"
 
 #define        BCLINK_WIN_DEFAULT      50      /* bcast link window size (default) */
 #define        BCLINK_WIN_MIN          32      /* bcast minimum link window size */
@@ -434,3 +433,33 @@ void tipc_bcast_stop(struct net *net)
        kfree(tn->bcbase);
        kfree(tn->bcl);
 }
+
+void tipc_nlist_init(struct tipc_nlist *nl, u32 self)
+{
+       memset(nl, 0, sizeof(*nl));
+       INIT_LIST_HEAD(&nl->list);
+       nl->self = self;
+}
+
+void tipc_nlist_add(struct tipc_nlist *nl, u32 node)
+{
+       if (node == nl->self)
+               nl->local = true;
+       else if (u32_push(&nl->list, node))
+               nl->remote++;
+}
+
+void tipc_nlist_del(struct tipc_nlist *nl, u32 node)
+{
+       if (node == nl->self)
+               nl->local = false;
+       else if (u32_del(&nl->list, node))
+               nl->remote--;
+}
+
+void tipc_nlist_purge(struct tipc_nlist *nl)
+{
+       u32_list_purge(&nl->list);
+       nl->remote = 0;
+       nl->local = 0;
+}
index 855d53c64ab347ec5b37dc06a39e10748f7bf388..18f379198f8fb5fbdd3afbbce7e8c4d00cf65eed 100644 (file)
 struct tipc_node;
 struct tipc_msg;
 struct tipc_nl_msg;
-struct tipc_node_map;
+struct tipc_nlist;
+struct tipc_nitem;
 extern const char tipc_bclink_name[];
 
+struct tipc_nlist {
+       struct list_head list;
+       u32 self;
+       u16 remote;
+       bool local;
+};
+
+void tipc_nlist_init(struct tipc_nlist *nl, u32 self);
+void tipc_nlist_purge(struct tipc_nlist *nl);
+void tipc_nlist_add(struct tipc_nlist *nl, u32 node);
+void tipc_nlist_del(struct tipc_nlist *nl, u32 node);
+
 int tipc_bcast_init(struct net *net);
 void tipc_bcast_stop(struct net *net);
 void tipc_bcast_add_peer(struct net *net, struct tipc_link *l,
index 5a86df1e5fc20167ce2b48bd7b4e4309492fea6d..9be6592e4a6fa20c78995396ffa3dfcd1f19537a 100644 (file)
@@ -645,6 +645,39 @@ 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;
+
+       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 (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
  */
@@ -1022,11 +1055,6 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
        return skb->len;
 }
 
-struct u32_item {
-       struct list_head list;
-       u32 value;
-};
-
 bool u32_find(struct list_head *l, u32 value)
 {
        struct u32_item *item;
index c89bb3f5c364c7a342a0006d42d48b64d2f86db3..6ebdeb1d84a550dfdefb2f28a71d6a42ad2d5e88 100644 (file)
@@ -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 list_head *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);
@@ -116,6 +120,11 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
 int tipc_nametbl_init(struct net *net);
 void tipc_nametbl_stop(struct net *net);
 
+struct u32_item {
+       struct list_head list;
+       u32 value;
+};
+
 bool u32_push(struct list_head *l, u32 value);
 u32 u32_pop(struct list_head *l);
 bool u32_find(struct list_head *l, u32 value);