LTP GCOV extension - code coverage report
Current view: directory - net/tipc - cluster.c
Test: tipc.info
Date: 2003-08-07 Instrumented lines: 354
Code covered: 36.4 % Executed lines: 129

       1                 : /* 
       2                 :  * TIPC Linux kernel implementation
       3                 :  * Copyright (c) 2001-2003 Ericsson Research Canada
       4                 :  * Copyright (c) 2003 OSDL, Inc.
       5                 :  *
       6                 :  * This file is based on the original source code done by Jon Maloy
       7                 :  * (jon.maloy@ericsson.com) for TIPC version 0.96, available from
       8                 :  * http://tipc.sourceforge.net
       9                 :  ***************************************************************************
      10                 :  * This program is free software; you can redistribute it and/or modify
      11                 :  * it under the terms of the GNU General Public License as published by
      12                 :  * the Free Software Foundation; either version 2 of the License, or
      13                 :  * (at your option) any later version.
      14                 :  *   
      15                 :  * This program is distributed in the hope that it will be useful,
      16                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      17                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18                 :  * GNU General Public License for more details.
      19                 :  *  
      20                 :  * You should have received a copy of the GNU General Public License
      21                 :  * along with this program; if not, write to the Free Software
      22                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      23                 :  ***************************************************************************
      24                 :  * Alphabetical list of people who have worked on this file:
      25                 :  *      - Mark Haverkamp        (markh@osdl.org)
      26                 :  *      - Mika Kukkonen         (mika@osdl.org)
      27                 :  *      - Rusty Lynch           (rusty@linux.intel.com)
      28                 :  */
      29                 : 
      30                 : #include "cluster.h"
      31                 : #include "link.h"
      32                 : #include "local.h"
      33                 : 
      34                 : static void send_multicast(struct tipc_cluster *, struct sk_buff *, uint, uint);
      35                 : static struct sk_buff *prepare_routing_msg(uint dataSize);
      36                 : 
      37                 : struct tipc_node **localnodes = 0;
      38                 : struct tipc_cluster *cluster_pool = 0;
      39                 : 
      40                 : struct tipc_cluster *
      41                 : tipc_cluster_new(tipc_net_addr_t addr)
      42               1 : {
      43               1 :         struct tipc_zone *zone;
      44               1 :         struct tipc_cluster *cluster;
      45               1 :         uint zone_id = tipc_zone_id(addr);
      46               1 :         uint cluster_id = tipc_cluster_id(addr);
      47                 : 
      48                 :         assert(zone_id < TIPC_ZONE_AMOUNT);
      49                 :         assert(cluster_id < TIPC_CLUSTER_AMOUNT);
      50               1 :         zone = network.zones[zone_id];
      51               1 :         if (!zone) {
      52               1 :                 int status = 0;
      53                 : 
      54               1 :                 status = tipc_zone_new(zone_id);
      55               1 :                 if (status)
      56               0 :                         return 0;
      57               1 :                 zone = network.zones[zone_id];
      58                 :         }
      59               1 :         cluster = zone->clusters[cluster_id];
      60               1 :         if (!cluster) {
      61               2 :                 mem_cnew(cluster, cluster_pool, 12000);
      62               1 :                 zone->clusters[cluster_id] = cluster;
      63               1 :                 cluster->addr = tipc_make_addr(zone_id, cluster_id, 0);
      64               1 :                 cluster->nodes = tipc_local_addr(addr) ? localnodes : cluster->defaultarea;
      65               1 :                 cluster->highestDevice = TIPC_SLAVE_MIN_ID - 1;
      66               1 :                 cluster->highestnode = 0;
      67               1 :                 cluster->owner = zone;
      68               1 :                 netwsub_init(&cluster->subscription, cluster,
      69                 :                              (NS_Virtual) tipc_cluster_handleavailable,
      70                 :                              (NS_Virtual) tipc_cluster_handleunavailable);
      71                 :         }
      72               1 :         return cluster;
      73                 : }
      74                 : 
      75                 : tipc_net_addr_t
      76                 : tipc_cluster_nextnode(struct tipc_cluster * this, tipc_net_addr_t addr)
      77               0 : {
      78               0 :         struct tipc_node *p = 0;
      79               0 :         uint i = tipc_node_id(addr) + 1;
      80                 : 
      81               0 :         if (!this)
      82               0 :                 return addr;
      83                 :         dbg("tipc_cluster_nextnode() attempting %u->%u\n", i,
      84                 :             this->highestnode);
      85               0 :         for (; i <= this->highestnode; i++) {
      86               0 :                 p = this->nodes[i];
      87               0 :                 if (p && tipc_node_activelinks(p))
      88               0 :                         return p->addr;
      89                 :         }
      90                 :         dbg("tipc_cluster_nextnode() attempting %u->%u\n", i,
      91                 :             tipc_node_id(addr) - 1);
      92               0 :         for (i = 1; i < tipc_node_id(addr); i++) {
      93               0 :                 p = this->nodes[i];
      94               0 :                 if (p && tipc_node_activelinks(p))
      95               0 :                         return p->addr;
      96                 :         }
      97                 :         dbg("tipc_cluster_nextnode() returning %x\n", addr);
      98               0 :         return 0;
      99                 : }
     100                 : 
     101                 : void
     102                 : tipc_cluster_notifyavailable(struct tipc_cluster *this,
     103                 :                              struct net_reg * sc)
     104               1 : {
     105               1 :         uint z = tipc_zone_id(this->addr);
     106               1 :         uint s = tipc_cluster_id(this->addr);
     107               1 :         uint tstart = 1;
     108               1 :         uint tstop = this->highestnode;
     109               1 :         uint x;
     110                 : 
     111               3 :         for (x = 1; x <= 2; x++) {
     112               2 :                 uint p;
     113                 : 
     114              21 :                 for (p = tstart; p <= tstop; p++) {
     115              19 :                         struct tipc_node *node = this->nodes[p];
     116                 : 
     117              19 :                         if (node && tipc_node_available(node)) {
     118                 :                                 dbg(" cluster_notify: calling %p->%p for node:%x,hi dev = %i \n", sc, sc->handleAvailableF, tipc_make_addr(z, s, p), this->highestDevice);
     119               2 :                                 sc->handleAvailableF(sc->object,
     120                 :                                                      tipc_make_addr(z, s, p));
     121                 :                         }
     122                 :                 }
     123               2 :                 tstart = TIPC_SLAVE_MIN_ID;
     124               2 :                 tstop = this->highestDevice;
     125                 :         }
     126                 : }
     127                 : 
     128                 : void
     129                 : tipc_cluster_reportlinks(struct tipc_cluster *this, LinkSubscription * sc)
     130               0 : {
     131               0 :         uint tstart = 1;
     132               0 :         uint tstop = this->highestnode;
     133               0 :         uint x;
     134                 : 
     135               0 :         for (x = 1; x <= 2; x++) {
     136               0 :                 uint p;
     137                 : 
     138               0 :                 for (p = tstart; p <= tstop; p++) {
     139               0 :                         struct tipc_node *node = this->nodes[p];
     140                 : 
     141               0 :                         if (node && tipc_node_available(node)) {
     142               0 :                                 tipc_node_reportlinks(node, sc);
     143                 :                         }
     144                 :                 }
     145               0 :                 tstart = TIPC_SLAVE_MIN_ID;
     146               0 :                 tstop = this->highestDevice;
     147                 :         }
     148                 : }
     149                 : 
     150                 : void
     151                 : tipc_cluster_attachnode(struct tipc_cluster *this, struct tipc_node *p)
     152               2 : {
     153               2 :         uint pno = tipc_node_id(p->addr);
     154                 : 
     155                 :         assert(pno > 0);
     156                 :         assert(pno <=
     157                 :                ((tipc_local_addr(p->addr)) ? TIPC_SLAVE_MAX_ID :
     158                 :                 TIPC_NODE_MAX_ID));
     159                 :         assert(this->nodes[pno] == 0);
     160               2 :         this->nodes[pno] = p;
     161                 : }
     162                 : 
     163                 : void
     164                 : tipc_cluster_handleunavailable(struct tipc_cluster *this, tipc_net_addr_t addr)
     165               0 : {
     166               0 :         struct net_reg *cursor;
     167               0 :         uint *h =
     168               0 :             tipc_slave_addr(addr) ? &this->highestDevice : &this->highestnode;
     169               0 :         uint tstop = tipc_slave_addr(addr) ? TIPC_SLAVE_MIN_ID : 1;
     170                 : 
     171               0 :         if (tipc_node_id(addr) == *h) {
     172               0 :                 while ((--(*h) >= tstop)
     173                 :                        && !tipc_node_available(this->nodes[*h])) ;
     174                 :         }
     175               0 :         cursor = this->subscription.next;
     176               0 :         while (cursor != &this->subscription) {
     177               0 :                 struct net_reg *nx = cursor->next;
     178                 : 
     179               0 :                 netwsub_handleUnavailable(cursor, addr);        /* Might unlink */
     180               0 :                 cursor = nx;
     181                 :         }
     182               0 :         zone_handleunavailable(this->owner, addr);
     183                 : }
     184                 : 
     185                 : void
     186                 : tipc_cluster_handleavailable(struct tipc_cluster *this, tipc_net_addr_t addr)
     187               2 : {
     188               2 :         struct net_reg *s = this->subscription.next;
     189               2 :         uint p = tipc_node_id(addr);
     190                 : 
     191                 :         dbg(" Subn_handleAvailable(this = %p, addr =%x,node = %x)\n", this,
     192                 :             addr, p);
     193               2 :         if (tipc_slave_addr(p)) {
     194               0 :                 if (p > this->highestDevice)
     195               0 :                         this->highestDevice = p;
     196               2 :         } else if (p > this->highestnode)
     197               2 :                 this->highestnode = p;
     198                 :         dbg(" Subn_handleAvailable 1 s = %p,%p\n", s, &this->subscription);
     199               2 :         while (s != &this->subscription) {
     200               0 :                 struct net_reg *next = s->next;
     201                 : 
     202                 :                 dbg(" Subn_handleAvailable 2 s->next: %p \n", s->next);
     203               0 :                 netwsub_handleAvailable(s, addr);
     204                 :                 dbg(" Subn_handleAvailable 3 s->next: %p \n", s->next);
     205               0 :                 s = next;
     206                 :         }
     207                 :         dbg(" Subn_handleAvailable: calling zone: HandleAv\n");
     208               2 :         zone_handleavailable(this->owner, addr);
     209                 : }
     210                 : 
     211                 : /* Deterministic and fair selection of a router to the given remote cluster */
     212                 : tipc_net_addr_t
     213                 : tipc_cluster_selectrouter(struct tipc_cluster *this, uint ref)
     214               0 : {
     215               0 :         uint ulim = this->highestnode;
     216               0 :         uint mask;
     217               0 :         uint tstart;
     218               0 :         uint p;
     219                 : 
     220                 :         assert(!tipc_local_addr(this->addr));
     221               0 :         if (!ulim)
     222               0 :                 return 0;
     223                 : 
     224                 :         /* Start entry must be random */
     225               0 :         mask = TIPC_NODE_MAX_ID;
     226               0 :         while (mask > ulim)
     227               0 :                 mask >>= 1;
     228               0 :         tstart = ref & mask;
     229               0 :         p = tstart;
     230                 : 
     231                 :         /* Lookup upwards with wrap-around */
     232               0 :         do {
     233               0 :                 if (tipc_node_available(this->nodes[p]))
     234               0 :                         break;
     235               0 :         } while (++p <= ulim);
     236               0 :         if (p > ulim) {
     237               0 :                 p = 1;
     238               0 :                 do {
     239               0 :                         if (tipc_node_available(this->nodes[p]))
     240               0 :                                 break;
     241               0 :                 } while (++p < tstart);
     242               0 :                 if (p == tstart)
     243               0 :                         return 0;
     244                 :         }
     245                 :         assert(p <= ulim);
     246               0 :         return tipc_node_selectrouter(this->nodes[p], ref);
     247                 : }
     248                 : 
     249                 : /* Deterministic and fair selection of a node within the given  */
     250                 : /* remote cluster                                                 */
     251                 : struct tipc_node *
     252                 : tipc_cluster_selectremotenode(struct tipc_cluster *this, uint selector)
     253               0 : {
     254               0 :         uint mask = TIPC_NODE_MAX_ID;
     255               0 :         uint start_entry;
     256               0 :         uint p;
     257                 : 
     258                 :         assert(!tipc_local_addr(this->addr));
     259               0 :         if (!this->highestnode)
     260               0 :                 return 0;
     261                 : 
     262                 :         /* Start entry must be random */
     263               0 :         while (mask > this->highestnode) {
     264               0 :                 mask >>= 1;
     265                 :         }
     266               0 :         start_entry = (selector & mask) ? selector & mask : 1u;
     267                 :         assert(start_entry <= this->highestnode);
     268                 : 
     269                 :         /* Lookup upwards with wrap-around */
     270               0 :         for (p = start_entry; p <= this->highestnode; p++) {
     271               0 :                 if (tipc_node_activelinks(this->nodes[p]))
     272               0 :                         return this->nodes[p];
     273                 :         }
     274               0 :         for (p = 1; p < start_entry; p++) {
     275               0 :                 if (tipc_node_activelinks(this->nodes[p]))
     276               0 :                         return this->nodes[p];
     277                 :         }
     278               0 :         return 0;
     279                 : }
     280                 : 
     281                 : /* Routing table management: See description in node.cc */
     282                 : static struct sk_buff *
     283                 : prepare_routing_msg(uint dataSize)
     284               2 : {
     285               2 :         uint size = INTERNAL_HDR_SIZE + dataSize;
     286               2 :         struct sk_buff *buf;
     287               2 :         tipc_msg_hdr_t *msg;
     288                 : 
     289               2 :         buf = buf_acquire(size);
     290               2 :         msg = buf_msg(buf);
     291               2 :         memset((char *) msg, 0, size);
     292               4 :         set_msg_version(msg, MSG_VERSION_1);
     293               4 :         set_msg_user(msg, ROUTING_MANAGER);
     294               4 :         set_hdr_size(msg, INTERNAL_HDR_SIZE);
     295               2 :         set_prev_node(msg, tipc_my_addr);
     296               4 :         set_msg_size(msg, size);
     297               2 :         return buf;
     298                 : }
     299                 : 
     300                 : void
     301                 : tipc_cluster_multicastnewroute(struct tipc_cluster *this, tipc_net_addr_t dest,
     302                 :                                uint lower, uint upper)
     303               2 : {
     304               2 :         struct sk_buff *buf = prepare_routing_msg(0);
     305               2 :         tipc_msg_hdr_t *msg = buf_msg(buf);
     306                 : 
     307               2 :         set_remote_addr(msg, dest);
     308               4 :         set_msg_type(msg, ROUTE_ADDITION);
     309               2 :         send_multicast(this, buf, lower, upper);
     310                 : }
     311                 : 
     312                 : void
     313                 : tipc_cluster_multicastlostroute(struct tipc_cluster *this, tipc_net_addr_t dest,
     314                 :                                 uint lower, uint upper)
     315               0 : {
     316               0 :         struct sk_buff *buf = prepare_routing_msg(0);
     317               0 :         tipc_msg_hdr_t *msg = buf_msg(buf);
     318                 : 
     319               0 :         set_remote_addr(msg, dest);
     320               0 :         set_msg_type(msg, ROUTE_REMOVAL);
     321               0 :         send_multicast(this, buf, lower, upper);
     322                 : }
     323                 : 
     324                 : void
     325                 : tipc_cluster_senddeviceroutes(struct tipc_cluster *this, tipc_net_addr_t dest)
     326               2 : {
     327               2 :         uint highest = this->highestDevice;
     328               2 :         struct sk_buff *buf;
     329               2 :         tipc_msg_hdr_t *msg;
     330               2 :         uint i;
     331               2 :         uint send = 0;
     332               2 :         Link *l;
     333                 : 
     334                 :         assert(!tipc_slave_addr(dest));
     335                 :         assert(tipc_local_addr(dest));
     336                 :         assert(tipc_local_addr(this->addr));
     337               2 :         if (highest <= TIPC_SLAVE_MIN_ID)
     338               0 :                 return;
     339               0 :         buf = prepare_routing_msg(highest - TIPC_SLAVE_MIN_ID + 1);
     340               0 :         msg = buf_msg(buf);
     341               0 :         set_remote_addr(msg, this->addr);
     342               0 :         set_msg_type(msg, DP_ROUTING_TABLE);
     343               0 :         for (i = TIPC_SLAVE_MIN_ID; i <= highest; i++) {
     344               0 :                 if (this->nodes[i]
     345                 :                     && tipc_node_activelinks(this->nodes[i])) {
     346               0 :                         send = 1;
     347               0 :                         set_data_octet(msg, i);
     348                 :                 }
     349                 :         }
     350               0 :         l = link_select(dest, 4);
     351               0 :         if (l && send)
     352               0 :                 link_sendBuf(l, buf);
     353                 :         else
     354               0 :                 buf_discard(buf);
     355                 : }
     356                 : 
     357                 : void
     358                 : tipc_cluster_sendexternalroutes(struct tipc_cluster *this, tipc_net_addr_t dest)
     359               2 : {
     360               2 :         uint send = 0;
     361               2 :         uint highest = this->highestnode;
     362               2 :         struct sk_buff *buf;
     363               2 :         tipc_msg_hdr_t *msg;
     364               2 :         uint i;
     365               2 :         Link *l;
     366                 : 
     367               2 :         if (tipc_local_addr(this->addr))
     368               0 :                 return;
     369                 :         assert(!tipc_slave_addr(dest));
     370                 :         assert(tipc_local_addr(dest));
     371               0 :         highest = this->highestnode;
     372                 :         dbg(" Ordering prep msg: highest = %i (%i)\n", highest, highest + 1);
     373               0 :         buf = prepare_routing_msg(highest + 1);
     374               0 :         msg = buf_msg(buf);
     375               0 :         set_remote_addr(msg, this->addr);
     376               0 :         set_msg_type(msg, EXT_ROUTING_TABLE);
     377                 : 
     378               0 :         for (i = 1; i <= highest; i++) {
     379               0 :                 if (this->nodes[i]
     380                 :                     && tipc_node_activelinks(this->nodes[i])) {
     381               0 :                         send = 1;
     382                 :                         dbg(" Setting octet %i (%i)\n", i, i);
     383               0 :                         set_data_octet(msg, i);
     384                 :                 }
     385                 :         }
     386                 : 
     387               0 :         l = link_select(dest, 4);
     388               0 :         if (l && send)
     389               0 :                 link_sendBuf(l, buf);
     390                 :         else
     391               0 :                 buf_discard(buf);
     392                 : 
     393                 : }
     394                 : 
     395                 : void
     396                 : tipc_cluster_sendlocalroutes(struct tipc_cluster *this, tipc_net_addr_t dest)
     397               0 : {
     398               0 :         uint send = 0;
     399               0 :         uint highest = this->highestnode;
     400               0 :         struct sk_buff *buf;
     401               0 :         tipc_msg_hdr_t *msg;
     402               0 :         uint i;
     403               0 :         Link *l;
     404                 : 
     405                 :         assert(tipc_slave_addr(dest));
     406                 :         assert(tipc_local_addr(this->addr));
     407               0 :         buf = prepare_routing_msg(highest);
     408               0 :         msg = buf_msg(buf);
     409               0 :         set_remote_addr(msg, this->addr);
     410               0 :         set_msg_type(msg, LOCAL_ROUTING_TABLE);
     411               0 :         for (i = 1; i <= highest; i++) {
     412               0 :                 if (this->nodes[i]
     413                 :                     && tipc_node_activelinks(this->nodes[i])) {
     414               0 :                         send = 1;
     415               0 :                         set_data_octet(msg, i);
     416                 :                 }
     417                 :         }
     418                 : 
     419               0 :         l = link_select(dest, 4);
     420               0 :         if (l && send)
     421               0 :                 link_sendBuf(l, buf);
     422                 :         else
     423               0 :                 buf_discard(buf);
     424                 : }
     425                 : 
     426                 : void
     427                 : tipc_cluster_handleroutingtablemsg(struct sk_buff *buf)
     428               0 : {
     429                 :         dbg(" Rec routing msg\n");
     430                 :         {
     431               0 :                 tipc_msg_hdr_t *msg = buf_msg(buf);
     432               0 :                 tipc_net_addr_t addr = get_remote_addr(msg);
     433               0 :                 uint z = tipc_zone_id(addr);
     434               0 :                 uint s = tipc_cluster_id(addr);
     435               0 :                 uint router = get_prev_node(msg);
     436               0 :                 struct tipc_cluster *this = 0;
     437                 : 
     438               0 :                 if (!network.zones[z]->clusters[1])
     439               0 :                         this = network.zones[z]->clusters[1];
     440                 :                 dbg(" Creating cluster for %x\n", get_remote_addr(msg));
     441               0 :                 if (!this)
     442               0 :                         this = tipc_cluster_new(get_remote_addr(msg));
     443                 :                 dbg(" Created cluster\n");
     444               0 :                 switch (get_msg_type(msg)) {
     445                 :                 case LOCAL_ROUTING_TABLE:
     446                 :                         {
     447                 :                                 assert(tipc_slave_addr(tipc_my_addr));
     448                 :                         }
     449                 :                 case EXT_ROUTING_TABLE:
     450                 :                         {
     451               0 :                                 __u8 *ptable =
     452               0 :                                     UD(buf)->data + get_hdr_size(msg);
     453               0 :                                 uint p;
     454               0 :                                 uint tableSize =
     455               0 :                                     get_msg_size(msg) - get_hdr_size(msg);
     456                 : 
     457               0 :                                 for (p = 1; p < tableSize; p++) {
     458               0 :                                         if (ptable[p]) {
     459               0 :                                                 struct tipc_node *node =
     460               0 :                                                     this->nodes[p];
     461               0 :                                                 if (!node)
     462               0 :                                                         node =
     463                 :                                                             tipc_node_new
     464                 :                                                             (tipc_make_addr
     465                 :                                                              (z, s, p));
     466               0 :                                                 tipc_node_addrouter(node,
     467                 :                                                                     router);
     468                 :                                         }
     469                 :                                 }
     470               0 :                                 break;
     471                 :                         }
     472                 :                 case DP_ROUTING_TABLE:
     473                 :                         {
     474               0 :                                 __u8 *ptable =
     475               0 :                                     UD(buf)->data + get_hdr_size(msg);
     476               0 :                                 uint p;
     477               0 :                                 uint tableSize =
     478               0 :                                     get_msg_size(msg) - get_hdr_size(msg);
     479                 : 
     480                 :                                 assert(!tipc_slave_addr(tipc_my_addr));
     481                 :                                 assert(tipc_local_addr(this->addr));
     482               0 :                                 for (p = 1; p < tableSize; p++) {
     483               0 :                                         if (ptable[p]) {
     484               0 :                                                 struct tipc_node *node =
     485                 :                                                     this->nodes[p +
     486               0 :                                                                 TIPC_SLAVE_MIN_ID];
     487               0 :                                                 if (!node)
     488               0 :                                                         node =
     489                 :                                                             tipc_node_new
     490                 :                                                             (tipc_make_addr
     491                 :                                                              (z, s,
     492                 :                                                               p +
     493                 :                                                               TIPC_SLAVE_MIN_ID));
     494               0 :                                                 tipc_node_addrouter(node,
     495                 :                                                                     router);
     496                 :                                         }
     497                 :                                 }
     498               0 :                                 break;
     499                 :                         }
     500                 :                 case ROUTE_ADDITION:
     501                 :                         {
     502               0 :                                 struct tipc_node *node;
     503                 : 
     504                 :                                 dbg(" ROUTE ADD\n");
     505               0 :                                 if (!tipc_slave_addr(tipc_my_addr)) {
     506                 :                                         assert(!tipc_local_addr(this->addr)
     507                 :                                                ||
     508                 :                                                tipc_slave_addr(get_remote_addr
     509                 :                                                                (msg)));
     510                 :                                 } else {
     511                 :                                         assert(tipc_local_addr(this->addr)
     512                 :                                                &&
     513                 :                                                !tipc_slave_addr(get_remote_addr
     514                 :                                                                 (msg)));
     515                 :                                 }
     516               0 :                                 node =
     517                 :                                     this->
     518               0 :                                     nodes[tipc_node_id(get_remote_addr(msg))];
     519               0 :                                 if (!node)
     520               0 :                                         node =
     521               0 :                                             tipc_node_new(get_remote_addr(msg));
     522               0 :                                 tipc_node_addrouter(node, router);
     523               0 :                                 break;
     524                 :                         }
     525                 :                 case ROUTE_REMOVAL:
     526                 :                         {
     527               0 :                                 struct tipc_node *node;
     528                 : 
     529               0 :                                 if (!tipc_slave_addr(tipc_my_addr)) {
     530                 :                                         assert(!tipc_local_addr(this->addr)
     531                 :                                                ||
     532                 :                                                tipc_slave_addr(get_remote_addr
     533                 :                                                                (msg)));
     534                 :                                 } else {
     535                 :                                         assert(tipc_local_addr(this->addr)
     536                 :                                                &&
     537                 :                                                !tipc_slave_addr(get_remote_addr
     538                 :                                                                 (msg)));
     539                 :                                 }
     540               0 :                                 node =
     541                 :                                     this->
     542               0 :                                     nodes[tipc_node_id(get_remote_addr(msg))];
     543               0 :                                 if (node)
     544               0 :                                         tipc_node_removerouter(node, router);
     545                 :                                 break;
     546                 :                         }
     547                 :                 default:{
     548                 :                                 assert
     549                 :                                     (!"Illegal routing manager message received\n");
     550                 :                         }
     551                 :                 }
     552               0 :                 buf_discard(buf);
     553                 :         }
     554                 : }
     555                 : 
     556                 : void
     557                 : tipc_cluster_removeasrouter(struct tipc_cluster *this, tipc_net_addr_t router)
     558               0 : {
     559               0 :         uint start_entry = 1;
     560               0 :         uint tstop = this->highestnode;
     561               0 :         uint p;
     562                 : 
     563               0 :         if (tipc_slave_addr(router))
     564               0 :                 return;         /* Device nodes can not be routers */
     565               0 :         if (tipc_local_addr(this->addr)) {   /* No routes to local system nodes */
     566               0 :                 start_entry = TIPC_SLAVE_MIN_ID;
     567               0 :                 tstop = this->highestDevice;
     568                 :         }
     569               0 :         for (p = start_entry; p <= tstop; p++) {
     570               0 :                 struct tipc_node *node = this->nodes[p];
     571                 : 
     572               0 :                 if (node)
     573               0 :                         tipc_node_removerouter(node, router);
     574                 :         }
     575                 : }
     576                 : 
     577                 : tipc_net_addr_t
     578                 : tipc_cluster_getrouter(tipc_net_addr_t dest)
     579               0 : {
     580               0 :         struct tipc_cluster *this = 0;
     581               0 :         uint i = 1;
     582                 : 
     583               0 :         this = network.zones[tipc_zone_id(dest)]->clusters[1];
     584               0 :         for (; i <= this->highestnode; i++) {
     585               0 :                 if (this->nodes[i]) {
     586               0 :                         return tipc_node_selectrouter(this->nodes[i], 0);
     587                 :                 }
     588                 :         }
     589               0 :         return 0;
     590                 : }
     591                 : 
     592                 : /* Multicast message to local nodes  available via direct link  */
     593                 : static void
     594                 : send_multicast(struct tipc_cluster *this, struct sk_buff *buf, uint lower,
     595                 :                uint upper)
     596               2 : {
     597               2 :         uint tstop;
     598               2 :         uint i;
     599                 : 
     600                 :         assert(lower <= upper);
     601                 :         assert(((lower >= 1) && (lower <= TIPC_NODE_MAX_ID)) ||
     602                 :                ((lower >= TIPC_SLAVE_MIN_ID)
     603                 :                 && (lower <= TIPC_SLAVE_MAX_ID)));
     604                 :         assert(((upper >= 1) && (upper <= TIPC_NODE_MAX_ID))
     605                 :                || ((upper >= TIPC_SLAVE_MIN_ID)
     606                 :                    && (upper <= TIPC_SLAVE_MAX_ID)));
     607                 :         assert(tipc_local_addr(this->addr));
     608                 : 
     609               2 :         tstop =
     610                 :             tipc_slave_addr(upper) ? this->highestDevice : this->highestnode;
     611               2 :         if (tstop > upper)
     612               2 :                 tstop = upper;
     613                 : 
     614               2 :         for (i = lower; i <= tstop; i++) {
     615               0 :                 Link *l;
     616               0 :                 struct sk_buff *b;
     617               0 :                 struct tipc_node *p = this->nodes[i];
     618                 : 
     619               0 :                 if (!p || (i == tipc_my_node.id))
     620               0 :                         continue;
     621               0 :                 l = p->activeLinks[i & 7];
     622               0 :                 if (!l)
     623               0 :                         continue;
     624               0 :                 b = buf_copy(buf, UD(buf)->data);
     625               0 :                 link_sendBuf(l, b);
     626                 :         }
     627               2 :         buf_discard(buf);
     628                 : }
     629                 : 
     630                 : /* Broadcast message to all nodes within cluster. */
     631                 : void
     632                 : tipc_cluster_broadcast(struct tipc_cluster *this, struct sk_buff *buf)
     633              34 : {
     634              34 :         uint start_entry = 1;
     635              34 :         uint tstop = this->highestnode;
     636              34 :         uint x;
     637                 : 
     638                 :         assert(tipc_local_addr(this->addr)); /* For now */
     639             102 :         for (x = 1; x <= 2; x++) {
     640              68 :                 uint i;
     641                 : 
     642             714 :                 for (i = start_entry; i <= tstop; i++) {
     643             646 :                         Link *l;
     644             646 :                         struct sk_buff *b;
     645             646 :                         struct tipc_node *p = this->nodes[i];
     646                 : 
     647             646 :                         if (!p)
     648              68 :                                 continue;
     649              68 :                         l = p->activeLinks[i & 7];
     650              68 :                         if (!l) {
     651               0 :                                 l = link_select(p->addr, i);
     652               0 :                                 if (!l)
     653              68 :                                         continue;
     654                 :                         }
     655              68 :                         b = buf_copy(buf, UD(buf)->data);
     656                 :                         set_dest_node(buf_msg(b),
     657                 :                                       tipc_make_addr(tipc_my_zone.id,
     658              68 :                                                      tipc_my_cluster.id, i));
     659              68 :                         link_sendBuf(l, b);
     660                 :                 }
     661              68 :                 start_entry = TIPC_SLAVE_MIN_ID;
     662              68 :                 tstop = this->highestDevice;
     663                 :         }
     664              34 :         buf_discard(buf);
     665                 : }
     666                 : 
     667                 : void
     668                 : tipc_cluster_addtonodelist(struct tipc_cluster *this, tipc_node_list * list)
     669               4 : {
     670               4 :         uint start = 1;
     671               4 :         uint stop = this->highestnode;
     672               4 :         uint i;
     673                 : 
     674               4 :         if ((list->count * sizeof (list->nodes)) >= 65404)
     675               4 :                 return;
     676              12 :         for (i = 1; i <= 2; i++) {
     677               8 :                 uint p;
     678                 : 
     679              84 :                 for (p = start; p <= stop; p++) {
     680              76 :                         struct tipc_node *node = this->nodes[p];
     681                 : 
     682              76 :                         if (node) {
     683               8 :                                 list->nodes[list->count].addr = node->addr;
     684               8 :                                 list->nodes[list->count++].available =
     685                 :                                     tipc_node_available(node);
     686                 :                         }
     687                 :                 }
     688               8 :                 start = TIPC_SLAVE_MIN_ID;
     689               8 :                 stop = this->highestDevice;
     690                 :         }
     691                 : }
     692                 : 
     693                 : /* This array must be initiated before first message arrives:     */
     694                 : void
     695                 : tipc_cluster_init(void)
     696               1 : {
     697               1 :         localnodes =
     698                 :             (struct tipc_node **) mem_alloc((TIPC_SLAVE_MAX_ID + 1) *
     699                 :                                             sizeof (struct tipc_node *));
     700                 :         assert(localnodes);
     701                 :         memset(localnodes, 0,
     702               1 :                (TIPC_SLAVE_MAX_ID + 1) * sizeof (struct tipc_node *));
     703                 : }

Generated by: LTP GCOV extension version 1.1