1b97bf3fdSPer Liden /* 2b97bf3fdSPer Liden * net/tipc/name_distr.c: TIPC name distribution code 3b97bf3fdSPer Liden * 4a5325ae5SErik Hugne * Copyright (c) 2000-2006, 2014, Ericsson AB 5431697ebSAllan Stephens * Copyright (c) 2005, 2010-2011, Wind River Systems 6b97bf3fdSPer Liden * All rights reserved. 7b97bf3fdSPer Liden * 8b97bf3fdSPer Liden * Redistribution and use in source and binary forms, with or without 9b97bf3fdSPer Liden * modification, are permitted provided that the following conditions are met: 10b97bf3fdSPer Liden * 119ea1fd3cSPer Liden * 1. Redistributions of source code must retain the above copyright 129ea1fd3cSPer Liden * notice, this list of conditions and the following disclaimer. 139ea1fd3cSPer Liden * 2. Redistributions in binary form must reproduce the above copyright 149ea1fd3cSPer Liden * notice, this list of conditions and the following disclaimer in the 159ea1fd3cSPer Liden * documentation and/or other materials provided with the distribution. 169ea1fd3cSPer Liden * 3. Neither the names of the copyright holders nor the names of its 179ea1fd3cSPer Liden * contributors may be used to endorse or promote products derived from 189ea1fd3cSPer Liden * this software without specific prior written permission. 199ea1fd3cSPer Liden * 209ea1fd3cSPer Liden * Alternatively, this software may be distributed under the terms of the 219ea1fd3cSPer Liden * GNU General Public License ("GPL") version 2 as published by the Free 229ea1fd3cSPer Liden * Software Foundation. 23b97bf3fdSPer Liden * 24b97bf3fdSPer Liden * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25b97bf3fdSPer Liden * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26b97bf3fdSPer Liden * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27b97bf3fdSPer Liden * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 28b97bf3fdSPer Liden * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29b97bf3fdSPer Liden * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30b97bf3fdSPer Liden * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31b97bf3fdSPer Liden * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32b97bf3fdSPer Liden * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33b97bf3fdSPer Liden * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34b97bf3fdSPer Liden * POSSIBILITY OF SUCH DAMAGE. 35b97bf3fdSPer Liden */ 36b97bf3fdSPer Liden 37b97bf3fdSPer Liden #include "core.h" 38b97bf3fdSPer Liden #include "link.h" 39b97bf3fdSPer Liden #include "name_distr.h" 40b97bf3fdSPer Liden 41b97bf3fdSPer Liden /** 423f8375feSAllan Stephens * struct publ_list - list of publications made by this node 433f8375feSAllan Stephens * @list: circular list of publications 443f8375feSAllan Stephens * @list_size: number of entries in list 45b97bf3fdSPer Liden */ 463f8375feSAllan Stephens struct publ_list { 473f8375feSAllan Stephens struct list_head list; 483f8375feSAllan Stephens u32 size; 493f8375feSAllan Stephens }; 50b97bf3fdSPer Liden 51a909804fSAllan Stephens static struct publ_list publ_zone = { 52a909804fSAllan Stephens .list = LIST_HEAD_INIT(publ_zone.list), 53a909804fSAllan Stephens .size = 0, 54a909804fSAllan Stephens }; 55a909804fSAllan Stephens 563f8375feSAllan Stephens static struct publ_list publ_cluster = { 573f8375feSAllan Stephens .list = LIST_HEAD_INIT(publ_cluster.list), 583f8375feSAllan Stephens .size = 0, 593f8375feSAllan Stephens }; 60b97bf3fdSPer Liden 61a909804fSAllan Stephens static struct publ_list publ_node = { 62a909804fSAllan Stephens .list = LIST_HEAD_INIT(publ_node.list), 63a909804fSAllan Stephens .size = 0, 64a909804fSAllan Stephens }; 65a909804fSAllan Stephens 66a909804fSAllan Stephens static struct publ_list *publ_lists[] = { 67a909804fSAllan Stephens NULL, 68a909804fSAllan Stephens &publ_zone, /* publ_lists[TIPC_ZONE_SCOPE] */ 69a909804fSAllan Stephens &publ_cluster, /* publ_lists[TIPC_CLUSTER_SCOPE] */ 70a909804fSAllan Stephens &publ_node /* publ_lists[TIPC_NODE_SCOPE] */ 71a909804fSAllan Stephens }; 72a909804fSAllan Stephens 73a909804fSAllan Stephens 74a5325ae5SErik Hugne int sysctl_tipc_named_timeout __read_mostly = 2000; 75a5325ae5SErik Hugne 76a5325ae5SErik Hugne /** 77a5325ae5SErik Hugne * struct tipc_dist_queue - queue holding deferred name table updates 78a5325ae5SErik Hugne */ 79a5325ae5SErik Hugne static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue); 80a5325ae5SErik Hugne 81a5325ae5SErik Hugne struct distr_queue_item { 82a5325ae5SErik Hugne struct distr_item i; 83a5325ae5SErik Hugne u32 dtype; 84a5325ae5SErik Hugne u32 node; 85a5325ae5SErik Hugne unsigned long expires; 86a5325ae5SErik Hugne struct list_head next; 87a5325ae5SErik Hugne }; 88a5325ae5SErik Hugne 89b97bf3fdSPer Liden /** 90b97bf3fdSPer Liden * publ_to_item - add publication info to a publication message 91b97bf3fdSPer Liden */ 92b97bf3fdSPer Liden static void publ_to_item(struct distr_item *i, struct publication *p) 93b97bf3fdSPer Liden { 94b97bf3fdSPer Liden i->type = htonl(p->type); 95b97bf3fdSPer Liden i->lower = htonl(p->lower); 96b97bf3fdSPer Liden i->upper = htonl(p->upper); 97b97bf3fdSPer Liden i->ref = htonl(p->ref); 98b97bf3fdSPer Liden i->key = htonl(p->key); 99b97bf3fdSPer Liden } 100b97bf3fdSPer Liden 101b97bf3fdSPer Liden /** 102b97bf3fdSPer Liden * named_prepare_buf - allocate & initialize a publication message 103b97bf3fdSPer Liden */ 104b97bf3fdSPer Liden static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) 105b97bf3fdSPer Liden { 106741d9eb7SAllan Stephens struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size); 107b97bf3fdSPer Liden struct tipc_msg *msg; 108b97bf3fdSPer Liden 109b97bf3fdSPer Liden if (buf != NULL) { 110b97bf3fdSPer Liden msg = buf_msg(buf); 111741d9eb7SAllan Stephens tipc_msg_init(msg, NAME_DISTRIBUTOR, type, INT_H_SIZE, dest); 112741d9eb7SAllan Stephens msg_set_size(msg, INT_H_SIZE + size); 113b97bf3fdSPer Liden } 114b97bf3fdSPer Liden return buf; 115b97bf3fdSPer Liden } 116b97bf3fdSPer Liden 117eab8c045SYing Xue void named_cluster_distribute(struct sk_buff *buf) 1188f92df6aSAllan Stephens { 119dbdf6d24SJon Paul Maloy struct sk_buff *obuf; 120dbdf6d24SJon Paul Maloy struct tipc_node *node; 121dbdf6d24SJon Paul Maloy u32 dnode; 1228f92df6aSAllan Stephens 1236c7a762eSYing Xue rcu_read_lock(); 124dbdf6d24SJon Paul Maloy list_for_each_entry_rcu(node, &tipc_node_list, list) { 125dbdf6d24SJon Paul Maloy dnode = node->addr; 126dbdf6d24SJon Paul Maloy if (in_own_node(dnode)) 127dbdf6d24SJon Paul Maloy continue; 128dbdf6d24SJon Paul Maloy if (!tipc_node_active_links(node)) 129dbdf6d24SJon Paul Maloy continue; 130dbdf6d24SJon Paul Maloy obuf = skb_copy(buf, GFP_ATOMIC); 131dbdf6d24SJon Paul Maloy if (!obuf) 1328f92df6aSAllan Stephens break; 133dbdf6d24SJon Paul Maloy msg_set_destnode(buf_msg(obuf), dnode); 1349fbfb8b1SJon Paul Maloy tipc_link_xmit(obuf, dnode, dnode); 1358f92df6aSAllan Stephens } 1366c7a762eSYing Xue rcu_read_unlock(); 1378f92df6aSAllan Stephens 1385f6d9123SAllan Stephens kfree_skb(buf); 1398f92df6aSAllan Stephens } 1408f92df6aSAllan Stephens 141b97bf3fdSPer Liden /** 1424323add6SPer Liden * tipc_named_publish - tell other nodes about a new publication by this node 143b97bf3fdSPer Liden */ 144eab8c045SYing Xue struct sk_buff *tipc_named_publish(struct publication *publ) 145b97bf3fdSPer Liden { 146b97bf3fdSPer Liden struct sk_buff *buf; 147b97bf3fdSPer Liden struct distr_item *item; 148b97bf3fdSPer Liden 149a909804fSAllan Stephens list_add_tail(&publ->local_list, &publ_lists[publ->scope]->list); 150a909804fSAllan Stephens publ_lists[publ->scope]->size++; 151b97bf3fdSPer Liden 1521110b8d3SAllan Stephens if (publ->scope == TIPC_NODE_SCOPE) 153eab8c045SYing Xue return NULL; 1541110b8d3SAllan Stephens 155b97bf3fdSPer Liden buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); 156b97bf3fdSPer Liden if (!buf) { 1572cf8aa19SErik Hugne pr_warn("Publication distribution failure\n"); 158eab8c045SYing Xue return NULL; 159b97bf3fdSPer Liden } 160b97bf3fdSPer Liden 161b97bf3fdSPer Liden item = (struct distr_item *)msg_data(buf_msg(buf)); 162b97bf3fdSPer Liden publ_to_item(item, publ); 163eab8c045SYing Xue return buf; 164b97bf3fdSPer Liden } 165b97bf3fdSPer Liden 166b97bf3fdSPer Liden /** 1674323add6SPer Liden * tipc_named_withdraw - tell other nodes about a withdrawn publication by this node 168b97bf3fdSPer Liden */ 169eab8c045SYing Xue struct sk_buff *tipc_named_withdraw(struct publication *publ) 170b97bf3fdSPer Liden { 171b97bf3fdSPer Liden struct sk_buff *buf; 172b97bf3fdSPer Liden struct distr_item *item; 173b97bf3fdSPer Liden 174b97bf3fdSPer Liden list_del(&publ->local_list); 175a909804fSAllan Stephens publ_lists[publ->scope]->size--; 176b97bf3fdSPer Liden 1771110b8d3SAllan Stephens if (publ->scope == TIPC_NODE_SCOPE) 178eab8c045SYing Xue return NULL; 1791110b8d3SAllan Stephens 180b97bf3fdSPer Liden buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); 181b97bf3fdSPer Liden if (!buf) { 1822cf8aa19SErik Hugne pr_warn("Withdrawal distribution failure\n"); 183eab8c045SYing Xue return NULL; 184b97bf3fdSPer Liden } 185b97bf3fdSPer Liden 186b97bf3fdSPer Liden item = (struct distr_item *)msg_data(buf_msg(buf)); 187b97bf3fdSPer Liden publ_to_item(item, publ); 188eab8c045SYing Xue return buf; 189b97bf3fdSPer Liden } 190b97bf3fdSPer Liden 191dbdf6d24SJon Paul Maloy /** 192e11aa059SAllan Stephens * named_distribute - prepare name info for bulk distribution to another node 193dbdf6d24SJon Paul Maloy * @msg_list: list of messages (buffers) to be returned from this function 194dbdf6d24SJon Paul Maloy * @dnode: node to be updated 195dbdf6d24SJon Paul Maloy * @pls: linked list of publication items to be packed into buffer chain 196e11aa059SAllan Stephens */ 197dbdf6d24SJon Paul Maloy static void named_distribute(struct list_head *msg_list, u32 dnode, 198dbdf6d24SJon Paul Maloy struct publ_list *pls) 199e11aa059SAllan Stephens { 200e11aa059SAllan Stephens struct publication *publ; 201e11aa059SAllan Stephens struct sk_buff *buf = NULL; 202e11aa059SAllan Stephens struct distr_item *item = NULL; 203dbdf6d24SJon Paul Maloy uint dsz = pls->size * ITEM_SIZE; 204dbdf6d24SJon Paul Maloy uint msg_dsz = (tipc_node_get_mtu(dnode, 0) / ITEM_SIZE) * ITEM_SIZE; 205dbdf6d24SJon Paul Maloy uint rem = dsz; 206dbdf6d24SJon Paul Maloy uint msg_rem = 0; 207e11aa059SAllan Stephens 208e11aa059SAllan Stephens list_for_each_entry(publ, &pls->list, local_list) { 209dbdf6d24SJon Paul Maloy /* Prepare next buffer: */ 210e11aa059SAllan Stephens if (!buf) { 211dbdf6d24SJon Paul Maloy msg_rem = min_t(uint, rem, msg_dsz); 212dbdf6d24SJon Paul Maloy rem -= msg_rem; 213dbdf6d24SJon Paul Maloy buf = named_prepare_buf(PUBLICATION, msg_rem, dnode); 214e11aa059SAllan Stephens if (!buf) { 2152cf8aa19SErik Hugne pr_warn("Bulk publication failure\n"); 216e11aa059SAllan Stephens return; 217e11aa059SAllan Stephens } 218e11aa059SAllan Stephens item = (struct distr_item *)msg_data(buf_msg(buf)); 219e11aa059SAllan Stephens } 220dbdf6d24SJon Paul Maloy 221dbdf6d24SJon Paul Maloy /* Pack publication into message: */ 222e11aa059SAllan Stephens publ_to_item(item, publ); 223e11aa059SAllan Stephens item++; 224dbdf6d24SJon Paul Maloy msg_rem -= ITEM_SIZE; 225dbdf6d24SJon Paul Maloy 226dbdf6d24SJon Paul Maloy /* Append full buffer to list: */ 227dbdf6d24SJon Paul Maloy if (!msg_rem) { 228dbdf6d24SJon Paul Maloy list_add_tail((struct list_head *)buf, msg_list); 229e11aa059SAllan Stephens buf = NULL; 230e11aa059SAllan Stephens } 231e11aa059SAllan Stephens } 232e11aa059SAllan Stephens } 233e11aa059SAllan Stephens 234b97bf3fdSPer Liden /** 2354323add6SPer Liden * tipc_named_node_up - tell specified node about all publications by this node 236b97bf3fdSPer Liden */ 237dbdf6d24SJon Paul Maloy void tipc_named_node_up(u32 dnode) 238b97bf3fdSPer Liden { 239dbdf6d24SJon Paul Maloy LIST_HEAD(msg_list); 240dbdf6d24SJon Paul Maloy struct sk_buff *buf_chain; 2419aa88c2aSAllan Stephens 2424323add6SPer Liden read_lock_bh(&tipc_nametbl_lock); 243dbdf6d24SJon Paul Maloy named_distribute(&msg_list, dnode, &publ_cluster); 244dbdf6d24SJon Paul Maloy named_distribute(&msg_list, dnode, &publ_zone); 2454323add6SPer Liden read_unlock_bh(&tipc_nametbl_lock); 2469aa88c2aSAllan Stephens 247dbdf6d24SJon Paul Maloy /* Convert circular list to linear list and send: */ 248dbdf6d24SJon Paul Maloy buf_chain = (struct sk_buff *)msg_list.next; 249dbdf6d24SJon Paul Maloy ((struct sk_buff *)msg_list.prev)->next = NULL; 2509fbfb8b1SJon Paul Maloy tipc_link_xmit(buf_chain, dnode, dnode); 251b97bf3fdSPer Liden } 252b97bf3fdSPer Liden 253*a8f48af5SYing Xue static void tipc_publ_subscribe(struct publication *publ, u32 addr) 254*a8f48af5SYing Xue { 255*a8f48af5SYing Xue struct tipc_node *node; 256*a8f48af5SYing Xue 257*a8f48af5SYing Xue if (in_own_node(addr)) 258*a8f48af5SYing Xue return; 259*a8f48af5SYing Xue 260*a8f48af5SYing Xue node = tipc_node_find(addr); 261*a8f48af5SYing Xue if (!node) { 262*a8f48af5SYing Xue pr_warn("Node subscription rejected, unknown node 0x%x\n", 263*a8f48af5SYing Xue addr); 264*a8f48af5SYing Xue return; 265*a8f48af5SYing Xue } 266*a8f48af5SYing Xue 267*a8f48af5SYing Xue tipc_node_lock(node); 268*a8f48af5SYing Xue list_add_tail(&publ->nodesub_list, &node->publ_list); 269*a8f48af5SYing Xue tipc_node_unlock(node); 270*a8f48af5SYing Xue } 271*a8f48af5SYing Xue 272*a8f48af5SYing Xue static void tipc_publ_unsubscribe(struct publication *publ, u32 addr) 273*a8f48af5SYing Xue { 274*a8f48af5SYing Xue struct tipc_node *node; 275*a8f48af5SYing Xue 276*a8f48af5SYing Xue node = tipc_node_find(addr); 277*a8f48af5SYing Xue if (!node) 278*a8f48af5SYing Xue return; 279*a8f48af5SYing Xue 280*a8f48af5SYing Xue tipc_node_lock(node); 281*a8f48af5SYing Xue list_del_init(&publ->nodesub_list); 282*a8f48af5SYing Xue tipc_node_unlock(node); 283*a8f48af5SYing Xue } 284*a8f48af5SYing Xue 285b97bf3fdSPer Liden /** 286*a8f48af5SYing Xue * tipc_publ_purge - remove publication associated with a failed node 287b97bf3fdSPer Liden * 288b97bf3fdSPer Liden * Invoked for each publication issued by a newly failed node. 289b97bf3fdSPer Liden * Removes publication structure from name table & deletes it. 290b97bf3fdSPer Liden */ 291*a8f48af5SYing Xue static void tipc_publ_purge(struct publication *publ, u32 addr) 292b97bf3fdSPer Liden { 293b97bf3fdSPer Liden struct publication *p; 294f131072cSAllan Stephens 2954323add6SPer Liden write_lock_bh(&tipc_nametbl_lock); 2964323add6SPer Liden p = tipc_nametbl_remove_publ(publ->type, publ->lower, 297b97bf3fdSPer Liden publ->node, publ->ref, publ->key); 298431697ebSAllan Stephens if (p) 299*a8f48af5SYing Xue tipc_publ_unsubscribe(p, addr); 3004323add6SPer Liden write_unlock_bh(&tipc_nametbl_lock); 301f131072cSAllan Stephens 302f131072cSAllan Stephens if (p != publ) { 3032cf8aa19SErik Hugne pr_err("Unable to remove publication from failed node\n" 304f131072cSAllan Stephens " (type=%u, lower=%u, node=0x%x, ref=%u, key=%u)\n", 3052cf8aa19SErik Hugne publ->type, publ->lower, publ->node, publ->ref, 3062cf8aa19SErik Hugne publ->key); 307f131072cSAllan Stephens } 308f131072cSAllan Stephens 309f131072cSAllan Stephens kfree(p); 310f131072cSAllan Stephens } 311b97bf3fdSPer Liden 312*a8f48af5SYing Xue void tipc_publ_notify(struct list_head *nsub_list, u32 addr) 313*a8f48af5SYing Xue { 314*a8f48af5SYing Xue struct publication *publ, *tmp; 315*a8f48af5SYing Xue 316*a8f48af5SYing Xue list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) 317*a8f48af5SYing Xue tipc_publ_purge(publ, addr); 318*a8f48af5SYing Xue } 319*a8f48af5SYing Xue 320b97bf3fdSPer Liden /** 321f4ad8a4bSErik Hugne * tipc_update_nametbl - try to process a nametable update and notify 322f4ad8a4bSErik Hugne * subscribers 323f4ad8a4bSErik Hugne * 324f4ad8a4bSErik Hugne * tipc_nametbl_lock must be held. 325f4ad8a4bSErik Hugne * Returns the publication item if successful, otherwise NULL. 326f4ad8a4bSErik Hugne */ 3270fc4dffaSErik Hugne static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype) 328f4ad8a4bSErik Hugne { 329f4ad8a4bSErik Hugne struct publication *publ = NULL; 330f4ad8a4bSErik Hugne 331f4ad8a4bSErik Hugne if (dtype == PUBLICATION) { 332f4ad8a4bSErik Hugne publ = tipc_nametbl_insert_publ(ntohl(i->type), ntohl(i->lower), 333f4ad8a4bSErik Hugne ntohl(i->upper), 334f4ad8a4bSErik Hugne TIPC_CLUSTER_SCOPE, node, 335f4ad8a4bSErik Hugne ntohl(i->ref), ntohl(i->key)); 336f4ad8a4bSErik Hugne if (publ) { 337*a8f48af5SYing Xue tipc_publ_subscribe(publ, node); 3380fc4dffaSErik Hugne return true; 339f4ad8a4bSErik Hugne } 340f4ad8a4bSErik Hugne } else if (dtype == WITHDRAWAL) { 341f4ad8a4bSErik Hugne publ = tipc_nametbl_remove_publ(ntohl(i->type), ntohl(i->lower), 342f4ad8a4bSErik Hugne node, ntohl(i->ref), 343f4ad8a4bSErik Hugne ntohl(i->key)); 344f4ad8a4bSErik Hugne if (publ) { 345*a8f48af5SYing Xue tipc_publ_unsubscribe(publ, node); 346f4ad8a4bSErik Hugne kfree(publ); 3470fc4dffaSErik Hugne return true; 348f4ad8a4bSErik Hugne } 349f4ad8a4bSErik Hugne } else { 350f4ad8a4bSErik Hugne pr_warn("Unrecognized name table message received\n"); 351f4ad8a4bSErik Hugne } 3520fc4dffaSErik Hugne return false; 353f4ad8a4bSErik Hugne } 354f4ad8a4bSErik Hugne 355f4ad8a4bSErik Hugne /** 356a5325ae5SErik Hugne * tipc_named_add_backlog - add a failed name table update to the backlog 357a5325ae5SErik Hugne * 358a5325ae5SErik Hugne */ 359a5325ae5SErik Hugne static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) 360a5325ae5SErik Hugne { 361a5325ae5SErik Hugne struct distr_queue_item *e; 362a5325ae5SErik Hugne unsigned long now = get_jiffies_64(); 363a5325ae5SErik Hugne 364a5325ae5SErik Hugne e = kzalloc(sizeof(*e), GFP_ATOMIC); 365a5325ae5SErik Hugne if (!e) 366a5325ae5SErik Hugne return; 367a5325ae5SErik Hugne e->dtype = type; 368a5325ae5SErik Hugne e->node = node; 369a5325ae5SErik Hugne e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); 370a5325ae5SErik Hugne memcpy(e, i, sizeof(*i)); 371a5325ae5SErik Hugne list_add_tail(&e->next, &tipc_dist_queue); 372a5325ae5SErik Hugne } 373a5325ae5SErik Hugne 374a5325ae5SErik Hugne /** 375a5325ae5SErik Hugne * tipc_named_process_backlog - try to process any pending name table updates 376a5325ae5SErik Hugne * from the network. 377a5325ae5SErik Hugne */ 378a5325ae5SErik Hugne void tipc_named_process_backlog(void) 379a5325ae5SErik Hugne { 380a5325ae5SErik Hugne struct distr_queue_item *e, *tmp; 381a5325ae5SErik Hugne char addr[16]; 382a5325ae5SErik Hugne unsigned long now = get_jiffies_64(); 383a5325ae5SErik Hugne 384a5325ae5SErik Hugne list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) { 385a5325ae5SErik Hugne if (time_after(e->expires, now)) { 386a5325ae5SErik Hugne if (!tipc_update_nametbl(&e->i, e->node, e->dtype)) 387a5325ae5SErik Hugne continue; 388a5325ae5SErik Hugne } else { 389a5325ae5SErik Hugne tipc_addr_string_fill(addr, e->node); 390a5325ae5SErik Hugne pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %s key=%u\n", 391a5325ae5SErik Hugne e->dtype, ntohl(e->i.type), 392a5325ae5SErik Hugne ntohl(e->i.lower), 393a5325ae5SErik Hugne ntohl(e->i.upper), 394a5325ae5SErik Hugne addr, ntohl(e->i.key)); 395a5325ae5SErik Hugne } 396a5325ae5SErik Hugne list_del(&e->next); 397a5325ae5SErik Hugne kfree(e); 398a5325ae5SErik Hugne } 399a5325ae5SErik Hugne } 400a5325ae5SErik Hugne 401a5325ae5SErik Hugne /** 402247f0f3cSYing Xue * tipc_named_rcv - process name table update message sent by another node 403b97bf3fdSPer Liden */ 404247f0f3cSYing Xue void tipc_named_rcv(struct sk_buff *buf) 405b97bf3fdSPer Liden { 406b97bf3fdSPer Liden struct tipc_msg *msg = buf_msg(buf); 407b97bf3fdSPer Liden struct distr_item *item = (struct distr_item *)msg_data(msg); 408b97bf3fdSPer Liden u32 count = msg_data_sz(msg) / ITEM_SIZE; 409a5325ae5SErik Hugne u32 node = msg_orignode(msg); 410b97bf3fdSPer Liden 4114323add6SPer Liden write_lock_bh(&tipc_nametbl_lock); 412b97bf3fdSPer Liden while (count--) { 413a5325ae5SErik Hugne if (!tipc_update_nametbl(item, node, msg_type(msg))) 414a5325ae5SErik Hugne tipc_named_add_backlog(item, msg_type(msg), node); 415b97bf3fdSPer Liden item++; 416b97bf3fdSPer Liden } 417a5325ae5SErik Hugne tipc_named_process_backlog(); 4184323add6SPer Liden write_unlock_bh(&tipc_nametbl_lock); 4195f6d9123SAllan Stephens kfree_skb(buf); 420b97bf3fdSPer Liden } 421b97bf3fdSPer Liden 422b97bf3fdSPer Liden /** 4231110b8d3SAllan Stephens * tipc_named_reinit - re-initialize local publications 424b97bf3fdSPer Liden * 425945af1c3SAllan Stephens * This routine is called whenever TIPC networking is enabled. 4261110b8d3SAllan Stephens * All name table entries published by this node are updated to reflect 4271110b8d3SAllan Stephens * the node's new network address. 428b97bf3fdSPer Liden */ 4294323add6SPer Liden void tipc_named_reinit(void) 430b97bf3fdSPer Liden { 431b97bf3fdSPer Liden struct publication *publ; 432a909804fSAllan Stephens int scope; 433b97bf3fdSPer Liden 4344323add6SPer Liden write_lock_bh(&tipc_nametbl_lock); 435945af1c3SAllan Stephens 4361110b8d3SAllan Stephens for (scope = TIPC_ZONE_SCOPE; scope <= TIPC_NODE_SCOPE; scope++) 437a909804fSAllan Stephens list_for_each_entry(publ, &publ_lists[scope]->list, local_list) 438b97bf3fdSPer Liden publ->node = tipc_own_addr; 439945af1c3SAllan Stephens 4404323add6SPer Liden write_unlock_bh(&tipc_nametbl_lock); 441b97bf3fdSPer Liden } 442