LTP GCOV extension - code coverage report
Current view: directory - net/tipc - manager.c
Test: tipc.info
Date: 2003-08-07 Instrumented lines: 646
Code covered: 22.4 % Executed lines: 145

       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 "debug.h"
      31                 : #include "msg_buf.h"
      32                 : #include "message.h"
      33                 : #include "port.h"
      34                 : #include "link.h"
      35                 : #include "manager.h"
      36                 : #include "media.h"
      37                 : #include "name_table.h"
      38                 : #include "name_subscription.h"
      39                 : #include "reference.h"
      40                 : #include "local.h"
      41                 : 
      42                 : extern void __tipc_subscribe2network(tipc_id_t tipc_userid,
      43                 :                                      tipc_network_subscription_argv const
      44                 :                                      *uargs, tipc_id_t * subscriptionid,
      45                 :                                      unsigned int *initialcount);
      46                 : extern void __tipc_unsubscribe2network(tipc_id_t id);
      47                 : 
      48                 : typedef struct Manager {
      49                 :         tipc_id_t userid;
      50                 :         tipc_id_t portid;
      51                 :         tipc_id_t subscrid;
      52                 :         tipc_id_t conn_portid;
      53                 :         struct {
      54                 :                 uint nodes;
      55                 :                 uint links;
      56                 :                 LinkProbe parked;
      57                 :                 LinkRequest zone_req;
      58                 :                 LinkRequest node_req;
      59                 :         } zones[16];
      60                 :         LinkRequest pilot_reqs[16];
      61                 :         uint name_subscriptions;
      62                 :         uint network_subscriptions;
      63                 :         uint link_subscriptions;
      64                 : } Manager;
      65                 : 
      66                 : static struct Manager manager;
      67                 : 
      68                 : uint
      69                 : set_user_error(uint errorcode, const char *file, const uint line)
      70               0 : {
      71               0 :         char err_txt[512] = { 0, };
      72                 : 
      73               0 :         switch (errorcode) {
      74                 :         case tipc_invalid_message:
      75                 :                 {
      76               0 :                         sprintf(err_txt,
      77                 :                                 "TIPC: User Error:  Attempt to send invalid message at.\n");
      78               0 :                         break;
      79                 :                 }
      80                 :         case tipc_oversized_message:
      81                 :                 {
      82               0 :                         sprintf(err_txt,
      83                 :                                 "TIPC: User Error:  Sending oversized msg or more than 128 sections.\n");
      84               0 :                         break;
      85                 :                 }
      86                 :         case tipc_too_many_sections:
      87                 :                 {
      88               0 :                         sprintf(err_txt,
      89                 :                                 "TIPC: User Error:  Attempt to send more than 128 sections.\n");
      90               0 :                         break;
      91                 :                 }
      92                 :         case tipc_del_no_port:
      93                 :                 {
      94                 :                         /* Let this one pass without crashing the Capsule. It is not acceptable
      95                 :                            when the capsule is the Java VM. */
      96               0 :                         return 0;
      97                 :                 }
      98                 :         case tipc_invalid_reference:
      99                 :                 {
     100               0 :                         sprintf(err_txt,
     101                 :                                 "TIPC: User Error:  Attempt to access non-existing port or subscription.\n");
     102               0 :                         break;
     103                 :                 }
     104                 :         case tipc_invalid_args:
     105                 :                 {
     106               0 :                         sprintf(err_txt,
     107                 :                                 "TIPC: User Error:  Kernel call with illegal argument vector.\n");
     108               0 :                         break;
     109                 :                 }
     110                 :         case tipc_illegal_operation:
     111                 :                 {
     112               0 :                         sprintf(err_txt,
     113                 :                                 "TIPC: User Error:  Attempt to access port in wrong state.\n");
     114               0 :                         break;
     115                 :                 }
     116                 :         case tipc_publishing_connected_port:
     117                 :                 {
     118               0 :                         sprintf(err_txt,
     119                 :                                 "TIPC: User Error:  Publishing port name from connected port.\n");
     120               0 :                         break;
     121                 :                 }
     122                 :         case tipc_connecting_published_port:
     123                 :                 {
     124               0 :                         sprintf(err_txt,
     125                 :                                 "TIPC: User Error:  Attempt to connect published port.\n");
     126               0 :                         break;
     127                 :                 }
     128                 :         case tipc_connecting_connected_port:
     129                 :                 {
     130               0 :                         sprintf(err_txt,
     131                 :                                 "TIPC: User Error:  Attempt to connect already connected port.\n");
     132               0 :                         break;
     133                 :                 }
     134                 :         default:
     135                 :                 {
     136               0 :                         sprintf(err_txt,
     137                 :                                 "TIPC: User Error:  User error, unknown code %i",
     138                 :                                 errorcode);
     139                 :                 }
     140                 :         }
     141               0 :         strncat(err_txt, "Detected at: ", sizeof (err_txt) - strlen(err_txt));
     142               0 :         strncat(err_txt, file, sizeof (err_txt) - strlen(err_txt));
     143               0 :         sprintf(err_txt + strlen(err_txt), " line %u\n", line);
     144               0 :         err("%s\n", err_txt);
     145               0 :         return 1;
     146                 : }
     147                 : 
     148                 : void
     149                 : manager_cancelLinkReq(LinkRequest * r)
     150               0 : {
     151               0 :         if (r->timerRef)
     152               0 :                 os_cancelTimer(r->timerRef);
     153               0 :         memset(r, 0, sizeof (*r));
     154                 : }
     155                 : 
     156                 : void
     157                 : manager_sendLinkRequest(LinkRequest * r)
     158               0 : {
     159               0 :         struct tipc_link_addr addr;
     160                 : 
     161               0 :         r->timerRef = 0;
     162               0 :         if (r->addr) {               /* Pilot request goes forever */
     163               0 :                 if ((r->timerCount++ >= 10) || (!tipc_node_id(r->addr)
     164                 :                                                 &&
     165                 :                                                 (zone_linkcount
     166                 :                                                  (tipc_zone_id(r->addr)) >=
     167                 :                                                  2))) {
     168               0 :                         memset(r, 0, sizeof (*r));
     169               0 :                         return;
     170                 :                 }
     171                 :         }
     172                 :         assert(r->media);
     173               0 :         addr.media = r->media;
     174               0 :         addr.orig = tipc_my_addr;
     175               0 :         addr.dest = r->addr;
     176                 :         memcpy(&addr.dest_media, &r->media_addr,
     177               0 :                sizeof (struct tipc_media_addr));
     178               0 :         r->media->api->send_req(&addr);
     179               0 :         r->timerRef =
     180                 :             os_setTimer((TimeoutHandler) manager_sendLinkRequest, (void *) r,
     181                 :                         4000);
     182                 : }
     183                 : 
     184                 : void
     185                 : manager_requestLink(LinkRequest * r, tipc_net_addr_t addr,
     186                 :                     struct tipc_media *b,
     187                 :                     const struct tipc_media_addr *media_addr)
     188               0 : {
     189               0 :         if (r->timerRef)
     190               0 :                 return;         /* Duplicate request */
     191               0 :         memset(r, 0, sizeof (*r));
     192                 :         assert(b);
     193               0 :         r->addr = addr;
     194               0 :         r->media = b;
     195               0 :         memcpy(&r->media_addr, media_addr, sizeof (*media_addr));
     196               0 :         manager_sendLinkRequest(r);
     197                 : }
     198                 : 
     199                 : void
     200                 : tipc_manager_link_setup(const tipc_net_addr_t addr)
     201               0 : {
     202               0 :         uint z = tipc_zone_id(addr);
     203               0 :         uint ownLinks = zone_linkcount(z);
     204                 : 
     205               0 :         if (ownLinks >= 2)
     206               0 :                 return;
     207               0 :         if (manager.zones[z].nodes) {
     208               0 :                 uint addr_htonl = htonl(addr);
     209               0 :                 tipc_portname dest = { 1, TIPC_GET_MEDIA_INFO };
     210               0 :                 uint router = ownLinks ? 0 : tipc_cluster_getrouter(addr);
     211               0 :                 tipc_message_section msg;
     212                 : 
     213               0 :                 msg.data = (__u8 *) & addr_htonl;
     214               0 :                 msg.size = 4u;
     215               0 :                 __tipc_send2name(manager.portid, &dest, router, 1u, &msg);
     216                 :         }
     217                 : }
     218                 : 
     219                 : void
     220                 : manager_link_event(TipcLinkEvent * event)
     221               4 : {
     222               4 :         tipc_net_addr_t addr = event->addr;
     223               4 :         uint z = tipc_zone_id(addr);
     224               4 :         uint linkCount = zone_linkcount(z);
     225               4 :         Link *link = link_findByName((const char *) &event->name);
     226               4 :         uint up = event->up;
     227                 : 
     228                 :         assert(z);
     229               4 :         event->discard(event);
     230               4 :         if (tipc_zone_id(addr) == tipc_my_zone.id)
     231               0 :                 return;
     232               0 :         if (!up) {              /* Set up new link if necessary */
     233               0 :                 manager.zones[z].links--;
     234               0 :                 link_delete(link);
     235               0 :                 if (--linkCount < 2) {
     236               0 :                         os_setTimer((TimeoutHandler) tipc_manager_link_setup,
     237                 :                                     (void *) (z << 24), 2000);
     238                 :                 }
     239                 :         } else {
     240               0 :                 LinkRequest *r = &manager.zones[tipc_zone_id(addr)].node_req;
     241                 : 
     242               0 :                 if (r->addr == addr) {
     243               0 :                         manager_cancelLinkReq(r);
     244               0 :                         manager_forwardLinkProbe(&manager.
     245                 :                                                  zones[tipc_zone_id(addr)].
     246                 :                                                  parked);
     247                 :                 }
     248               0 :                 manager.zones[z].links++;
     249               0 :                 if (linkCount >= 2) {
     250               0 :                         manager_cancelLinkReq(&manager.
     251                 :                                               zones[tipc_zone_id(addr)].
     252                 :                                               zone_req);
     253               0 :                         if (linkCount > 2) { /* Link entropy check */
     254               0 :                                 tipc_portname dest =
     255               0 :                                     { 1, TIPC_CHECK_LINK_COUNT };
     256               0 :                                 tipc_message_section msg = { 0, 0 };
     257               0 :                                 uint i = linkCount;
     258                 : 
     259               0 :                                 while (i--) {
     260               0 :                                         __tipc_send2name(manager.portid, &dest,
     261                 :                                                          addr, 1u, &msg);
     262               0 :                                         addr = tipc_network_nextnode(addr);
     263                 :                                 }
     264                 :                         }
     265                 :                 }
     266                 :         }
     267                 :         info("-----> There is now %u links to zone %u\n",
     268               0 :              manager.zones[z].links, z);
     269                 : }
     270                 : 
     271                 : void
     272                 : manager_network_event(void *userdata,
     273                 :                       tipc_id_t subscriptionid, tipc_net_addr_t node, int up)
     274               2 : {
     275                 :         /* A new zone available ? */
     276               2 :         if (tipc_zone_id(node) != tipc_my_zone.id) {
     277               0 :                 uint zone = tipc_zone_id(node);
     278                 : 
     279               0 :                 if (!up) {
     280               0 :                         manager.zones[zone].nodes--;
     281               0 :                         return;
     282                 :                 }
     283               0 :                 if ((!manager.zones[zone].nodes++)
     284                 :                     || (zone_linkcount(zone) < 2)) {
     285               0 :                         tipc_manager_link_setup(zone << 24);
     286                 :                 }
     287                 :         } else {
     288                 :                 /* Indicate to remote network subscribers */
     289                 :         }
     290                 : }
     291                 : 
     292                 : void
     293                 : manager_forwardLinkProbe(const LinkProbe * p)
     294               0 : {
     295               0 :         struct tipc_media *b = media_find_by_name(p->cfg.media_name);
     296               0 :         uint linksToOtherZone =
     297               0 :             zone_linkcount(tipc_zone_id(ntohl(p->cfg.addr)));
     298               0 :         uint zoneSize = tipc_availablenodes(tipc_my_zone.id << 24);
     299               0 :         uint hopCount = ntohl(p->hopCount);
     300               0 :         uint foundLinks = ntohl(p->foundLinks);
     301               0 :         Link *link = 0;
     302               0 :         LinkProbe probe;
     303                 : 
     304               0 :         memcpy(&probe, p, sizeof (LinkProbe));
     305               0 :         link = link_find(ntohl(probe.cfg.addr), b->id);
     306               0 :         if (link)
     307               0 :                 probe.foundLinks = htonl(++foundLinks);
     308               0 :         if (ntohl(probe.foundLinks) >= 2)
     309               0 :                 return;
     310               0 :         if (linksToOtherZone < ntohl(probe.lowestLinkCountThisTour)) {
     311               0 :                 probe.lowestLinkCountThisTour = htonl(linksToOtherZone);
     312                 :         }
     313                 : 
     314                 :         /* Has the probe completed a zone tour ? */
     315               0 :         if (!(++hopCount % zoneSize)) {
     316               0 :                 probe.lowestLinkCount = probe.lowestLinkCountThisTour;
     317               0 :                 probe.lowestLinkCountThisTour = ~0u;
     318               0 :                 probe.foundLinks = 0;
     319                 :         }
     320               0 :         if (hopCount < (10 * zoneSize)) {
     321               0 :                 tipc_net_addr_t next = tipc_network_nextnode(tipc_my_addr);
     322               0 :                 tipc_portname dest = { 1, TIPC_FORWARD_LINK_REQUEST };
     323               0 :                 tipc_message_section msg;
     324                 : 
     325               0 :                 msg.data = (__u8 *) & probe;
     326               0 :                 msg.size = sizeof (LinkProbe);
     327               0 :                 probe.hopCount = htonl(hopCount);
     328               0 :                 __tipc_send2name(manager.portid, &dest, next, 1u, &msg);
     329                 :         }
     330                 : }
     331                 : 
     332                 : void
     333                 : tipc_manager_link_req(struct tipc_media *b, const tipc_net_addr_t orig,
     334                 :                       const tipc_net_addr_t dest,
     335                 :                       struct tipc_media_addr *media_addr)
     336               0 : {
     337                 :         /* A general request to unspecified destination ? */
     338               0 :         if (!dest) {
     339               0 :                 LinkRequest *r = &manager.zones[tipc_zone_id(orig)].node_req;
     340               0 :                 LinkProbe *probe = &manager.zones[tipc_zone_id(orig)].parked;
     341                 : 
     342               0 :                 if (r->addr || tipc_availablenodes(orig & 0xff000000))
     343               0 :                         return;
     344               0 :                 media_add_link(b, orig, media_addr);    /* Create pilot link */
     345                 : 
     346                 :                 /* Prepare a probe to be forwarded later */
     347               0 :                 memset(probe, 0, sizeof (probe));
     348               0 :                 probe->cfg.addr = htonl(orig);
     349               0 :                 probe->lowestLinkCountThisTour = ~0u;
     350                 :                 memcpy(&probe->cfg.media_addr, media_addr,
     351               0 :                        sizeof (struct tipc_media_addr));
     352               0 :                 strcpy(probe->cfg.media_name, b->name);
     353               0 :                 manager_requestLink(r, orig, b, (const struct tipc_media_addr *)
     354                 :                                     media_addr);
     355                 :         }
     356                 : 
     357                 :         /* A scoped request to this zone ? */
     358               0 :         else if (!tipc_node_id(dest)) {
     359               0 :                 LinkProbe probe;
     360                 : 
     361               0 :                 memset(&probe, 0, sizeof (probe));
     362               0 :                 probe.cfg.addr = htonl(orig);
     363               0 :                 probe.lowestLinkCountThisTour = ~0u;
     364                 :                 memcpy(&probe.cfg.media_addr, media_addr,
     365               0 :                        sizeof (struct tipc_media_addr));
     366               0 :                 strcpy(probe.cfg.media_name, b->name);
     367                 :                 assert(!tipc_cluster_id(dest));
     368               0 :                 manager_forwardLinkProbe(&probe);
     369                 :         }
     370                 : 
     371                 :         /* A specific request to this node ? */
     372                 :         else {
     373               0 :                 LinkRequest *r = &manager.zones[tipc_zone_id(orig)].node_req;
     374               0 :                 tipc_portname name = { 1, TIPC_LINK_REQUEST_ACCEPTED };
     375               0 :                 tipc_message_section msg = { 0, 0 };
     376               0 :                 Link *link = 0;
     377                 : 
     378               0 :                 link = link_find(orig, b->id);
     379                 :                 assert(dest == tipc_my_addr);
     380               0 :                 manager_cancelLinkReq(&manager.zones[tipc_zone_id(orig)].
     381                 :                                       zone_req);
     382                 : 
     383               0 :                 if (zone_linkcount(tipc_zone_id(orig)) < 2) {
     384                 :                         /* Race condition: mutual link requests. Needs special treatment: */
     385               0 :                         if (link || ((r->addr == orig) && (dest < orig))) {
     386               0 :                                 name.instance = TIPC_LINK_REQUEST_REJECTED;
     387               0 :                         } else if (!link) {
     388               0 :                                 media_add_link(b, orig, media_addr);
     389                 :                         }
     390               0 :                 } else if (!link) {
     391               0 :                         name.instance = TIPC_DROP_LINK_REQUEST;
     392                 :                 } else
     393               0 :                         return; /* Duplicate of accepted request. Ignore */
     394               0 :                 __tipc_send2name(manager.portid, &name, orig, 1u, &msg);
     395                 :         }
     396                 : }
     397                 : 
     398                 : uint
     399                 : tipc_createLink(const tipc_create_link_argv * argv)
     400               0 : {
     401               0 :         struct tipc_media *b = media_find_by_name(argv->media_name);
     402               0 :         uint i = 0;
     403               0 :         LinkRequest *r = &manager.pilot_reqs[i];
     404                 : 
     405               0 :         while (r->media) {
     406               0 :                 r = &manager.pilot_reqs[++i];
     407                 :         }
     408               0 :         if ((i > 15) || (!b))
     409               0 :                 return 1;
     410               0 :         manager_requestLink(r, 0, b, &argv->peer_addr);
     411               0 :         return 0;
     412                 : }
     413                 : 
     414                 : void
     415                 : manager_name_subscr_event(TipcNameEvent * ev)
     416               0 : {
     417               0 :         if (!ev->cancelled) {
     418               0 :                 tipc_command_result_msg rmsg;
     419               0 :                 tipc_message_section msg =
     420               0 :                     { (const __u8 *) &rmsg, sizeof (rmsg) };
     421               0 :                 memset(&rmsg, 0, sizeof (rmsg));
     422               0 :                 rmsg.command = htonl(TIPC_NAME_SUBSCRIBE);
     423               0 :                 rmsg.result_len = htonl(sizeof (rmsg.result.name_event));
     424               0 :                 rmsg.retval = 0;
     425                 :                 memcpy(&rmsg.userdata, &ev->subscription->userArea,
     426               0 :                        sizeof (rmsg.userdata));
     427               0 :                 rmsg.result.name_event.event = htonl(ev->event);
     428               0 :                 rmsg.result.name_event.type = htonl(ev->subscription->type);
     429               0 :                 rmsg.result.name_event.found_lower = htonl(ev->foundlower);
     430               0 :                 rmsg.result.name_event.found_upper = htonl(ev->foundupper);
     431               0 :                 __tipc_send((tipc_id_t) ev->subscription->userArea[7], 1u,
     432                 :                             &msg);
     433               0 :                 if (ev->event == tipc_subscription_timeout) {
     434               0 :                         tipc_nameUnsubscribe((uint) ev->subscription->
     435                 :                                              subscrRef);
     436               0 :                         __tipc_deleteport((tipc_id_t) ev->subscription->
     437                 :                                           userArea[7]);
     438                 :                 }
     439                 :         }
     440               0 :         ev->discard(ev);
     441                 : }
     442                 : 
     443                 : void
     444                 : manager_name_subscr_port_event(void *userdata,
     445                 :                                tipc_id_t portid, tipc_msg_error_code reason)
     446               0 : {
     447               0 :         int connected = 0;
     448                 : 
     449               0 :         tipc_isconnected(portid, &connected);
     450               0 :         if (connected)
     451               0 :                 tipc_disconnect(portid);
     452               0 :         __tipc_deleteport(portid);
     453               0 :         tipc_nameUnsubscribe((uint) userdata);
     454               0 :         manager.name_subscriptions--;
     455                 : }
     456                 : 
     457                 : void
     458                 : manager_netw_subscr_event(TipcNetworkEvent * ev)
     459               0 : {
     460               0 :         if (!ev->cancelled) {
     461               0 :                 tipc_command_result_msg rmsg;
     462               0 :                 tipc_message_section msg =
     463               0 :                     { (const __u8 *) &rmsg, sizeof (rmsg) };
     464               0 :                 memset(&rmsg, 0, sizeof (rmsg));
     465               0 :                 rmsg.command = htonl(TIPC_NETWORK_SUBSCRIBE);
     466               0 :                 rmsg.result_len = htonl(sizeof (rmsg.result.network_event));
     467               0 :                 rmsg.retval = 0;
     468                 :                 memcpy(&rmsg.userdata, &ev->subscription->userArea,
     469               0 :                        sizeof (rmsg.userdata));
     470               0 :                 rmsg.result.network_event.up = htonl(ev->up);
     471               0 :                 rmsg.result.network_event.addr = htonl(ev->addr);
     472               0 :                 __tipc_send((tipc_id_t) ev->subscription->userArea[7], 1u,
     473                 :                             &msg);
     474                 :         }
     475               0 :         ev->discard(ev);
     476                 : }
     477                 : 
     478                 : void
     479                 : manager_netw_subscr_port_event(void *userdata,
     480                 :                                tipc_id_t portid, tipc_msg_error_code reason)
     481               0 : {
     482               0 :         int connected = 0;
     483                 : 
     484               0 :         tipc_isconnected(portid, &connected);
     485               0 :         if (connected)
     486               0 :                 __tipc_disconnect(portid);
     487               0 :         __tipc_deleteport(portid);
     488               0 :         tipc_networkUnsubscribe((uint) userdata);
     489                 : }
     490                 : 
     491                 : void
     492                 : manager_link_subscr_event(TipcLinkEvent * ev)
     493               0 : {
     494               0 :         spin_lock_bh(&tipc_big_lock);
     495               0 :         if (!ev->cancelled) {
     496               0 :                 tipc_command_result_msg rmsg;
     497               0 :                 tipc_message_section msg =
     498               0 :                     { (const __u8 *) &rmsg, sizeof (rmsg) };
     499               0 :                 memset(&rmsg, 0, sizeof (rmsg));
     500               0 :                 rmsg.command = htonl(TIPC_LINK_SUBSCRIBE);
     501               0 :                 rmsg.result_len = htonl(sizeof (rmsg.result.link_event));
     502               0 :                 rmsg.retval = 0;
     503                 :                 memcpy(&rmsg.userdata, &ev->subscription->userArea,
     504               0 :                        sizeof (rmsg.userdata));
     505               0 :                 rmsg.result.link_event.up = htonl(ev->up);
     506               0 :                 rmsg.result.link_event.addr = htonl(ev->addr);
     507                 :                 memcpy(&rmsg.result.link_event.link_name, &ev->name,
     508               0 :                        sizeof (ev->name));
     509               0 :                 __tipc_send((tipc_id_t) ev->subscription->userArea[7], 1u,
     510                 :                             &msg);
     511                 :         }
     512               0 :         ev->discard(ev);
     513               0 :         spin_unlock_bh(&tipc_big_lock);
     514                 : }
     515                 : 
     516                 : void
     517                 : manager_link_subscr_port_event(void *userdata,
     518                 :                                tipc_id_t portid, tipc_msg_error_code reason)
     519               0 : {
     520               0 :         int connected = 0;
     521                 : 
     522               0 :         __tipc_isconnected(portid, &connected);
     523               0 :         if (connected)
     524               0 :                 __tipc_disconnect(portid);
     525               0 :         __tipc_deleteport(portid);
     526               0 :         tipc_linkUnsubscribe((uint) userdata);
     527                 : }
     528                 : 
     529                 : void
     530                 : manager_respond(tipc_message_section * const rmsg,
     531                 :                 uint section_count, tipc_portreference const *origin)
     532              24 : {
     533              24 :         if (origin) {
     534              24 :                 __tipc_send2port(manager.portid, origin, section_count, rmsg);
     535                 :         } else {
     536               0 :                 __tipc_send(manager.conn_portid, section_count, rmsg);
     537                 :         }
     538                 : }
     539                 : 
     540                 : void
     541                 : manager_command_event(const unsigned char *octets,
     542                 :                       unsigned int size, tipc_portreference const *origin)
     543              24 : {
     544              24 :         const tipc_command_msg *msg = (const tipc_command_msg *) octets;
     545              24 :         uint retval = htonl(1);
     546              24 :         const __u8 *failure_info = "Illegal arguments";
     547              24 :         uint result_len = htonl(strlen(failure_info) + 1);
     548              24 :         uint remains = 0;
     549              24 :         tipc_message_section rmsg[5] = { {octets, 20},  /* Command and user data */
     550                 :         {(unsigned char *) &retval, 4u},
     551                 :         {(unsigned char *) &result_len, 4u},
     552                 :         {(unsigned char *) &remains, 4u},
     553              24 :         {failure_info, ntohl(result_len)}
     554              24 :         };
     555              24 :         uint command = ntohl(msg->command);
     556                 : 
     557              24 :         if (size == sizeof (tipc_command_msg)) {
     558              24 :                 switch (command) {
     559                 :                 case TIPC_CREATE_LINK:
     560                 :                         {
     561               0 :                                 retval =
     562                 :                                     htonl(tipc_createLink
     563                 :                                           (&msg->argv.create_link));
     564               0 :                                 if (!retval) {
     565               0 :                                         result_len = 0;
     566               0 :                                         __tipc_send(manager.conn_portid, 4u,
     567                 :                                                     rmsg);
     568                 :                                 }
     569               0 :                                 break;
     570                 :                         }
     571                 :                 case TIPC_GET_LINKS:
     572                 :                         {
     573               2 :                                 const tipc_net_addr_t scope =
     574               4 :                                     ntohl(msg->argv.scope);
     575               2 :                                 if (tipc_valid_addr(scope)) {
     576               2 :                                         rmsg[4].data =
     577                 :                                             tipc_network_getlinks(scope);
     578               2 :                                         rmsg[4].size =
     579                 :                                             rmsg[4].data ? strlen(rmsg[4].
     580                 :                                                                   data) + 1 : 0;
     581               2 :                                         retval = 0;
     582               2 :                                         result_len = htonl(rmsg[4].size);
     583               2 :                                         manager_respond(rmsg, 5u, origin);
     584                 :                                 }
     585               2 :                                 break;
     586                 :                         }
     587                 :                 case TIPC_GET_LINK_STATISTICS:
     588                 :                         {
     589               8 :                                 char *stat_buf =
     590               8 :                                     kmalloc(STAT_BUF_SIZE, GFP_ATOMIC);
     591               8 :                                 if (stat_buf == NULL)
     592               8 :                                         break;
     593               8 :                                 tipc_linkStatistics(msg->argv.link_name,
     594                 :                                                     stat_buf, STAT_BUF_SIZE);
     595               8 :                                 rmsg[4].data = stat_buf;
     596               8 :                                 rmsg[4].size = strlen(stat_buf) + 1;
     597               8 :                                 result_len = htonl(rmsg[4].size);
     598               8 :                                 retval = 0;
     599               8 :                                 manager_respond(rmsg, 5u, origin);
     600               8 :                                 kfree(stat_buf);
     601               8 :                                 break;
     602                 :                         }
     603                 :                 case TIPC_RESET_LINK_STATISTICS:
     604                 :                         {
     605               0 :                                 tipc_resetLinkStatistics(msg->argv.link_name);
     606               0 :                                 retval = 0;
     607               0 :                                 result_len = 0;
     608               0 :                                 manager_respond(rmsg, 5u, origin);
     609               0 :                                 break;
     610                 :                         }
     611                 :                 case TIPC_BLOCK_LINK:
     612                 :                         {
     613               0 :                                 retval =
     614                 :                                     htonl(tipc_blockLink(msg->argv.link_name));
     615               0 :                                 if (!retval) {
     616               0 :                                         result_len = 0;
     617               0 :                                         __tipc_send(manager.conn_portid, 4u,
     618                 :                                                     rmsg);
     619                 :                                 }
     620               0 :                                 break;
     621                 :                         }
     622                 :                 case TIPC_UNBLOCK_LINK:
     623                 :                         {
     624               0 :                                 retval =
     625                 :                                     htonl(tipc_unblockLink
     626                 :                                           (msg->argv.link_name));
     627               0 :                                 if (!retval) {
     628               0 :                                         result_len = 0;
     629               0 :                                         __tipc_send(manager.conn_portid, 4u,
     630                 :                                                     rmsg);
     631                 :                                 }
     632               0 :                                 break;
     633                 :                         }
     634                 :                 case TIPC_REMOVE_LINK:
     635                 :                         {
     636               0 :                                 retval =
     637                 :                                     htonl(tipc_removeLink(msg->argv.link_name));
     638               0 :                                 if (!retval) {
     639               0 :                                         result_len = 0;
     640               0 :                                         __tipc_send(manager.conn_portid, 4u,
     641                 :                                                     rmsg);
     642                 :                                 }
     643               0 :                                 break;
     644                 :                         }
     645                 :                 case TIPC_GET_PEER_ADDRESS:
     646                 :                         {
     647               0 :                                 const struct tipc_media_addr *addr =
     648               0 :                                     tipc_getPeerAddress(msg->argv.link_name);
     649               0 :                                 rmsg[4].data = (const char *) addr;
     650               0 :                                 rmsg[4].size = sizeof (struct tipc_media_addr);
     651               0 :                                 result_len = htonl(rmsg[4].size);
     652               0 :                                 retval = 0;
     653               0 :                                 manager_respond(rmsg, 5u, origin);
     654               0 :                                 break;
     655                 :                         }
     656                 :                 case TIPC_SET_LINK_TOLERANCE:
     657                 :                         {
     658               0 :                                 tipc_configure_link_argv a;
     659                 : 
     660                 :                                 memcpy(&a, &msg->argv.configure_link,
     661               0 :                                        sizeof (a));
     662               0 :                                 a.value = ntohl(a.value);
     663               0 :                                 retval = htonl(tipc_setLinkTolerance(&a));
     664               0 :                                 if (!retval) {
     665               0 :                                         result_len = 0;
     666               0 :                                         __tipc_send(manager.conn_portid, 4u,
     667                 :                                                     rmsg);
     668                 :                                 }
     669               0 :                                 break;
     670                 :                         }
     671                 :                 case TIPC_SET_LINK_PRIORITY:
     672                 :                         {
     673               0 :                                 tipc_configure_link_argv a;
     674                 : 
     675                 :                                 memcpy(&a, &msg->argv.configure_link,
     676               0 :                                        sizeof (a));
     677               0 :                                 a.value = ntohl(a.value);
     678               0 :                                 retval = htonl(tipc_setLinkPriority(&a));
     679               0 :                                 if (!retval) {
     680               0 :                                         result_len = 0;
     681               0 :                                         __tipc_send(manager.conn_portid, 4u,
     682                 :                                                     rmsg);
     683                 :                                 }
     684               0 :                                 break;
     685                 :                         }
     686                 :                 case TIPC_SET_LINK_WINDOW:
     687                 :                         {
     688               0 :                                 tipc_configure_link_argv a;
     689                 : 
     690                 :                                 memcpy(&a, &msg->argv.configure_link,
     691               0 :                                        sizeof (a));
     692               0 :                                 a.value = ntohl(a.value);
     693               0 :                                 retval = htonl(tipc_setLinkWindow(&a));
     694               0 :                                 if (!retval) {
     695               0 :                                         result_len = 0;
     696               0 :                                         __tipc_send(manager.conn_portid, 4u,
     697                 :                                                     rmsg);
     698                 :                                 }
     699               0 :                                 break;
     700                 :                         }
     701                 :                 case TIPC_GET_NODES:
     702                 :                         {
     703               2 :                                 const tipc_net_addr_t scope =
     704               4 :                                     ntohl(msg->argv.scope);
     705               2 :                                 if (tipc_valid_addr(scope)) {
     706               2 :                                         struct tipc_node_list *s =
     707               2 :                                             tipc_network_getnodes(scope);
     708               2 :                                         uint count = s->count;
     709               2 :                                         uint p = 0;
     710                 : 
     711               2 :                                         rmsg[4].data =
     712                 :                                             (const __u8 *) &s->nodes[0];
     713               2 :                                         rmsg[4].size =
     714                 :                                             count * sizeof (s->nodes[0]);
     715               2 :                                         retval = 0;
     716               2 :                                         result_len = htonl(rmsg[4].size);
     717               8 :                                         for (; p < count; p++) {
     718               6 :                                                 s->nodes[p].addr =
     719               6 :                                                     htonl(s->nodes[p].addr);
     720               6 :                                                 s->nodes[p].available =
     721                 :                                                     htonl(s->nodes[p].
     722               6 :                                                           available);
     723                 :                                         }
     724               2 :                                         manager_respond(rmsg, 5u, origin);
     725                 :                                 }
     726               2 :                                 break;
     727                 :                         }
     728                 :                 case TIPC_GET_MEDIAS:
     729                 :                         {
     730               2 :                                 char *medias =
     731               2 :                                     kmalloc(STAT_BUF_SIZE, GFP_ATOMIC);
     732               2 :                                 if (medias == NULL)
     733               2 :                                         break;
     734               2 :                                 rmsg[4].data =
     735                 :                                     (const __u8 *) media_name_list(medias);
     736               2 :                                 rmsg[4].size =
     737                 :                                     strlen((const char *) rmsg[4].data) + 1;
     738               2 :                                 retval = 0;
     739               2 :                                 result_len = htonl(rmsg[4].size);
     740               2 :                                 manager_respond(rmsg, 5u, origin);
     741               2 :                                 kfree(medias);
     742                 : 
     743               2 :                                 break;
     744                 :                         }
     745                 :                 case TIPC_GET_MEDIA_TYPES:
     746                 :                         {
     747               2 :                                 char *medias =
     748               2 :                                     kmalloc(STAT_BUF_SIZE, GFP_ATOMIC);
     749               2 :                                 if (medias == NULL)
     750               2 :                                         break;
     751                 : 
     752               2 :                                 strcpy(medias, "<ethernet>\n<udp>\n");
     753               2 :                                 rmsg[4].data = (const __u8 *) medias;
     754               2 :                                 rmsg[4].size =
     755                 :                                     strlen((const char *) rmsg[4].data) + 1;
     756               2 :                                 retval = 0;
     757               2 :                                 result_len = htonl(rmsg[4].size);
     758               2 :                                 manager_respond(rmsg, 5u, origin);
     759               2 :                                 kfree(medias);
     760                 : 
     761               2 :                                 break;
     762                 :                         }
     763                 :                 case TIPC_ENABLE_MEDIA:
     764                 :                         {
     765               0 :                                 tipc_enable_media_argv argv;
     766                 : 
     767                 :                                 memcpy(&argv, &msg->argv.enable_media,
     768               0 :                                        sizeof (argv));
     769               0 :                                 argv.priority =
     770               0 :                                     ntohl(msg->argv.enable_media.priority);
     771               0 :                                 retval =
     772                 :                                     htonl(media_enable_by_name
     773                 :                                           ((const char *) &argv.name));
     774               0 :                                 if (!retval) {
     775               0 :                                         result_len = 0;
     776               0 :                                         __tipc_send(manager.conn_portid, 4u,
     777                 :                                                     rmsg);
     778                 :                                 }
     779                 : 
     780               0 :                                 break;
     781                 :                         }
     782                 :                 case TIPC_DISABLE_MEDIA:
     783                 :                         {
     784               0 :                                 retval =
     785                 :                                     htonl(media_disable_by_name
     786                 :                                           (msg->argv.media_name));
     787               0 :                                 if (!retval) {
     788               0 :                                         result_len = 0;
     789               0 :                                         __tipc_send(manager.conn_portid, 4u,
     790                 :                                                     rmsg);
     791                 :                                 }
     792                 : 
     793               0 :                                 break;
     794                 :                         }
     795                 :                 case TIPC_GET_PORTS:
     796                 :                         {
     797               2 :                                 TipcPortList *list = tipc_getPorts();
     798                 : 
     799               2 :                                 rmsg[4].data = (const __u8 *) &list->ports;
     800               2 :                                 rmsg[4].size = list->count * sizeof (uint);
     801               2 :                                 retval = 0;
     802               2 :                                 result_len = htonl(rmsg[4].size);
     803               2 :                                 manager_respond(rmsg, 5u, origin);
     804               2 :                                 break;
     805                 :                         }
     806                 :                 case TIPC_GET_PORT_STATISTICS:
     807                 :                         {
     808               6 :                                 char *pstats =
     809               6 :                                     kmalloc(STAT_BUF_SIZE, GFP_ATOMIC);
     810               6 :                                 if (pstats == NULL) {
     811               6 :                                         break;
     812                 :                                 }
     813               6 :                                 rmsg[4].data =
     814                 :                                     tipc_portStatistics(*(uint *) & msg->argv.
     815                 :                                                         port_ref, pstats,
     816                 :                                                         STAT_BUF_SIZE);
     817               6 :                                 rmsg[4].size = strlen(rmsg[4].data) + 1;
     818               6 :                                 retval = 0;
     819               6 :                                 result_len = htonl(rmsg[4].size);
     820               6 :                                 manager_respond(rmsg, 5u, origin);
     821               6 :                                 kfree(pstats);
     822               6 :                                 break;
     823                 :                         }
     824                 :                 case TIPC_RESET_PORT_STATISTICS:
     825                 :                         {
     826               0 :                                 retval = 0;
     827               0 :                                 result_len = 0;
     828               0 :                                 manager_respond(rmsg, 4u, origin);
     829               0 :                                 break;
     830                 :                         }
     831                 :                 case TIPC_GET_NAME_TABLE:
     832                 :                         {
     833               0 :                                 tipc_get_name_table_argv argv;
     834                 : 
     835               0 :                                 argv.type =
     836               0 :                                     ntohl(msg->argv.get_name_table.type);
     837               0 :                                 argv.depth =
     838               0 :                                     ntohl(msg->argv.get_name_table.depth);
     839               0 :                                 if (argv.depth > 2)
     840               0 :                                         break;
     841                 : #ifdef CONFIG_TIPC_DBG_BUF
     842                 :                                 rmsg[4].data =
     843                 :                                     (const __u8 *) tipc_getNameTable(&argv);
     844                 :                                 rmsg[4].size =
     845                 :                                     strlen((const char *) rmsg[4].data);
     846                 : #endif
     847               0 :                                 retval = 0;
     848               0 :                                 result_len = htonl(rmsg[4].size);
     849               0 :                                 manager_respond(rmsg, 5u, origin);
     850               0 :                                 break;
     851                 :                         }
     852                 :                 case TIPC_GET_ROUTING_TABLE:
     853                 :                         {
     854                 : #if 0
     855                 :                                 tipc_net_addr_t scope = ntohl(msg->argv.scope);
     856                 :                                 TipcRouteList *l;
     857                 :                                 uint i = 0;
     858                 : 
     859                 :                                 if (!tipc_valid_addr(scope))
     860                 :                                         break;
     861                 :                                 l = tipc_getRoutes(scope);
     862                 :                                 for (; l && (i < l->count); i++) {
     863                 :                                         l->routes[i].dest =
     864                 :                                             htonl(l->routes[i].dest);
     865                 :                                         l->routes[i].router =
     866                 :                                             htonl(l->routes[i].router);
     867                 :                                 }
     868                 :                                 rmsg[4].data = (const __u8 *) &l->routes;
     869                 :                                 rmsg[4].size = l->count * sizeof (l->routes);
     870                 : #endif
     871               0 :                                 rmsg[4].data =
     872                 :                                     "TIPC_GET_ROUTING_TABLE not implemented";
     873               0 :                                 rmsg[4].size = strlen(rmsg[4].data) + 1;
     874               0 :                                 retval = 0;
     875               0 :                                 result_len = htonl(rmsg[4].size);
     876               0 :                                 manager_respond(rmsg, 5u, origin);
     877                 :                                 break;
     878                 :                         }
     879                 :                 default:{
     880                 :                         }
     881                 :                 }
     882                 :         }
     883              24 :         if (retval) {
     884               0 :                 manager_respond(rmsg, 5u, origin);
     885                 :         }
     886                 : }
     887                 : 
     888                 : void
     889                 : manager_connection_message_event(void *userdata,
     890                 :                                  tipc_id_t portid,
     891                 :                                  const unsigned char *octets,
     892                 :                                  unsigned int size, void **dummy)
     893               0 : {
     894               0 :         spin_lock_bh(&tipc_big_lock);
     895               0 :         manager_command_event(octets, size, 0);
     896               0 :         spin_unlock_bh(&tipc_big_lock);
     897                 : }
     898                 : 
     899                 : void
     900                 : manager_named_message_event(void *userdata,
     901                 :                             tipc_id_t portid,
     902                 :                             const unsigned char *octets,
     903                 :                             unsigned int size,
     904                 :                             tipc_portreference const *origin,
     905                 :                             tipc_portname const *destination,
     906                 :                             tipc_msg_importance importance, void **dummy)
     907              24 : {
     908              24 :         tipc_net_addr_t orig = origin->node;
     909              24 :         const tipc_command_msg *msg = (const tipc_command_msg *) octets;
     910              24 :         uint retval = htonl(1);
     911              24 :         const __u8 *failure_info = "Illegal arguments";
     912              24 :         uint result_len = htonl(strlen(failure_info) + 1);
     913              24 :         uint remains = 0;
     914              24 :         tipc_message_section rmsg[5] = { {octets, 20},  /* Command and user data */
     915                 :         {(unsigned char *) &retval, 4u},
     916                 :         {(unsigned char *) &result_len, 4u},
     917                 :         {(unsigned char *) &remains, 4u},
     918              24 :         {failure_info, ntohl(result_len)}
     919              24 :         };
     920              24 :         uint command = ntohl(msg->command);
     921                 : 
     922              72 :         spin_lock_bh(&tipc_big_lock);
     923              24 :         if ((size == sizeof (tipc_command_msg)) || (command <= 306)) {
     924              24 :                 switch (command) {
     925                 :                 case TIPC_NAME_SUBSCRIBE:
     926                 :                         {
     927               0 :                                 TipcNameSubscription *s;
     928               0 :                                 TipcNameSubscribeArgv argv;
     929                 : 
     930               0 :                                 if (manager.name_subscriptions > 1000)
     931               0 :                                         break;
     932               0 :                                 argv.type =
     933               0 :                                     ntohl(msg->argv.name_subscribe.type);
     934               0 :                                 argv.lower =
     935               0 :                                     ntohl(msg->argv.name_subscribe.lower);
     936               0 :                                 argv.upper =
     937               0 :                                     ntohl(msg->argv.name_subscribe.upper);
     938               0 :                                 argv.timeout =
     939               0 :                                     ntohl(msg->argv.name_subscribe.timeout);
     940               0 :                                 argv.handleEvent = manager_name_subscr_event;
     941               0 :                                 s = tipc_nameSubscribe(&argv);
     942               0 :                                 if (s) {
     943               0 :                                         tipc_createport_argv a;
     944               0 :                                         void *ev = (void *)
     945               0 :                                             manager_name_subscr_port_event;
     946                 : 
     947               0 :                                         retval = 0;
     948                 :                                         memcpy(&s->userArea, &msg->userdata,
     949               0 :                                                sizeof (msg->userdata));
     950               0 :                                         a.userdata = (void *) s->subscrRef;
     951               0 :                                         a.importance = tipc_high_importance;
     952               0 :                                         a.connected_error_cb =
     953                 :                                             (tipc_connected_error_event) ev;
     954               0 :                                         a.named_message_cb =
     955                 :                                             (tipc_named_message_event) ev;
     956               0 :                                         a.connected_message_cb =
     957                 :                                             (tipc_connected_message_event) ev;
     958               0 :                                         a.continue_event_cb = 0;
     959               0 :                                         __tipc_createport(manager.userid, &a,
     960                 :                                                           (uint *) & s->
     961                 :                                                           userArea[7]);
     962               0 :                                         __tipc_connect2port(s->userArea[7],
     963                 :                                                             origin);
     964               0 :                                         __tipc_send(s->userArea[7], 4u, rmsg);       /* Establish connection */
     965               0 :                                         manager.name_subscriptions++;
     966                 :                                 }
     967               0 :                                 break;
     968                 :                         }
     969                 :                 case TIPC_NETWORK_SUBSCRIBE:
     970                 :                         {
     971               0 :                                 TipcNetworkSubscription *s;
     972               0 :                                 TipcNetworkSubscribeArgv argv;
     973                 : 
     974               0 :                                 if (manager.network_subscriptions > 200)
     975               0 :                                         break;
     976               0 :                                 argv.addr = ntohl(msg->argv.scope);
     977               0 :                                 argv.handleEvent = manager_netw_subscr_event;
     978               0 :                                 s = tipc_networkSubscribe(&argv);
     979               0 :                                 if (s) {
     980               0 :                                         tipc_createport_argv a;
     981               0 :                                         void *ev = (void *)
     982               0 :                                             manager_netw_subscr_port_event;
     983                 : 
     984               0 :                                         retval = 0;
     985                 :                                         memcpy(&s->userArea, &msg->userdata,
     986               0 :                                                sizeof (msg->userdata));
     987               0 :                                         a.userdata = (void *) s->subscrRef;
     988               0 :                                         a.importance = tipc_high_importance;
     989               0 :                                         a.connected_error_cb =
     990                 :                                             (tipc_connected_error_event) ev;
     991               0 :                                         a.named_message_cb =
     992                 :                                             (tipc_named_message_event) ev;
     993               0 :                                         a.connected_message_cb =
     994                 :                                             (tipc_connected_message_event) ev;
     995               0 :                                         a.continue_event_cb = 0;
     996               0 :                                         __tipc_createport(manager.userid, &a,
     997                 :                                                           (uint *) & s->
     998                 :                                                           userArea[7]);
     999               0 :                                         __tipc_connect2port(s->userArea[7],
    1000                 :                                                             origin);
    1001               0 :                                         __tipc_send(s->userArea[7], 4u, rmsg);       /* Establish connection */
    1002               0 :                                         manager.network_subscriptions++;
    1003                 :                                 }
    1004               0 :                                 break;
    1005                 :                         }
    1006                 :                 case TIPC_LINK_SUBSCRIBE:
    1007                 :                         {
    1008               0 :                                 TipcLinkSubscription *s;
    1009               0 :                                 TipcLinkSubscribeArgv argv;
    1010                 : 
    1011               0 :                                 if (manager.link_subscriptions > 60)
    1012               0 :                                         break;
    1013               0 :                                 argv.handleEvent = manager_link_subscr_event;
    1014               0 :                                 s = tipc_linkSubscribe(&argv);
    1015               0 :                                 if (s) {
    1016               0 :                                         tipc_createport_argv a;
    1017               0 :                                         void *ev = (void *)
    1018               0 :                                             manager_link_subscr_port_event;
    1019                 : 
    1020               0 :                                         retval = 0;
    1021               0 :                                         result_len = 0;
    1022                 :                                         memcpy(&s->userArea, &msg->userdata,
    1023               0 :                                                sizeof (msg->userdata));
    1024               0 :                                         a.userdata = (void *) s->subscrRef;
    1025               0 :                                         a.importance = tipc_high_importance;
    1026               0 :                                         a.connected_error_cb =
    1027                 :                                             (tipc_connected_error_event) ev;
    1028               0 :                                         a.named_message_cb =
    1029                 :                                             (tipc_named_message_event) ev;
    1030               0 :                                         a.connected_message_cb =
    1031                 :                                             (tipc_connected_message_event) ev;
    1032               0 :                                         a.continue_event_cb = 0;
    1033               0 :                                         __tipc_createport(manager.userid, &a,
    1034                 :                                                           (uint *) & s->
    1035                 :                                                           userArea[7]);
    1036               0 :                                         __tipc_connect2port(s->userArea[7],
    1037                 :                                                             origin);
    1038               0 :                                         __tipc_send(s->userArea[7], 4u, rmsg);       /* Establish connection */
    1039               0 :                                         manager.link_subscriptions++;
    1040                 :                                 }
    1041               0 :                                 break;
    1042                 :                         }
    1043                 :                 case TIPC_BLOCK_LINK:
    1044                 :                 case TIPC_UNBLOCK_LINK:
    1045                 :                 case TIPC_REMOVE_LINK:
    1046                 :                 case TIPC_CREATE_LINK:
    1047                 :                 case TIPC_SET_LINK_TOLERANCE:
    1048                 :                 case TIPC_SET_LINK_PRIORITY:
    1049                 :                 case TIPC_SET_LINK_WINDOW:
    1050                 :                 case TIPC_ENABLE_MEDIA:
    1051                 :                 case TIPC_DISABLE_MEDIA:
    1052                 :                         {
    1053               0 :                                 int connected;
    1054                 : 
    1055               0 :                                 __tipc_isconnected(manager.conn_portid,
    1056                 :                                                    &connected);
    1057               0 :                                 if (connected) {
    1058               0 :                                         rmsg[4].data =
    1059                 :                                             "Access denied: Manager connection exists\n";
    1060               0 :                                         rmsg[4].size = strlen(rmsg[4].data) + 1;
    1061               0 :                                         result_len = htonl(rmsg[4].size);
    1062               0 :                                         retval = 1;
    1063               0 :                                         break;
    1064                 :                                 }
    1065                 :                                 assert(origin);
    1066               0 :                                 __tipc_connect2port(manager.conn_portid,
    1067                 :                                                     origin);
    1068                 :                         }
    1069                 :                 case TIPC_GET_LINKS:
    1070                 :                 case TIPC_GET_LINK_STATISTICS:
    1071                 :                 case TIPC_RESET_LINK_STATISTICS:
    1072                 :                 case TIPC_GET_PEER_ADDRESS:
    1073                 :                 case TIPC_GET_NODES:
    1074                 :                 case TIPC_GET_MEDIAS:
    1075                 :                 case TIPC_GET_MEDIA_TYPES:
    1076                 :                 case TIPC_GET_PORTS:
    1077                 :                 case TIPC_GET_PORT_STATISTICS:
    1078                 :                 case TIPC_RESET_PORT_STATISTICS:
    1079                 :                 case TIPC_GET_NAME_TABLE:
    1080                 :                 case TIPC_GET_ROUTING_TABLE:
    1081                 :                         {
    1082              24 :                                 manager_command_event(octets, size, origin);
    1083              24 :                                 retval = 0;     /* Send no response from here */
    1084              24 :                                 break;
    1085                 :                         }
    1086                 :                         /* Core internal calls related to inter zone link configuration: */
    1087                 :                 case TIPC_GET_MEDIA_INFO:
    1088                 :                         {
    1089               0 :                                 const tipc_net_addr_t addr =
    1090               0 :                                     ntohl(*(const tipc_net_addr_t *) octets);
    1091               0 :                                 Link *link = link_select(addr, 0);
    1092               0 :                                 tipc_portname dest = { 1, TIPC_MEDIA_ADDRESS };
    1093               0 :                                 LinkConfigInfo cfg;
    1094               0 :                                 tipc_message_section msg;
    1095                 : 
    1096               0 :                                 msg.data = (__u8 *) & cfg;
    1097               0 :                                 msg.size = sizeof (cfg);
    1098               0 :                                 if (!link)
    1099               0 :                                         break;
    1100                 :                                 memcpy(&cfg.media_addr, &link->rep.mediaAddr,
    1101               0 :                                        sizeof (struct tipc_media_addr));
    1102               0 :                                 strcpy(cfg.media_name, link->media->name);
    1103               0 :                                 cfg.addr = htonl(addr);
    1104               0 :                                 __tipc_send2name(manager.portid, &dest,
    1105                 :                                                  origin->node, 1u, &msg);
    1106               0 :                                 retval = 0;
    1107               0 :                                 break;
    1108                 :                         }
    1109                 :                 case TIPC_MEDIA_ADDRESS:
    1110                 :                         {
    1111               0 :                                 const LinkConfigInfo *cfg =
    1112               0 :                                     (const LinkConfigInfo *) octets;
    1113               0 :                                 tipc_net_addr_t addr =
    1114               0 :                                     0xff000000 & ntohl(cfg->addr);
    1115               0 :                                 LinkRequest *r =
    1116               0 :                                     &manager.zones[tipc_zone_id(addr)].zone_req;
    1117               0 :                                 manager_requestLink(r, addr,
    1118                 :                                                     media_find_by_name(cfg->
    1119                 :                                                                        media_name),
    1120                 :                                                     &cfg->media_addr);
    1121               0 :                                 retval = 0;
    1122               0 :                                 break;
    1123                 :                         }
    1124                 :                 case TIPC_FORWARD_LINK_REQUEST:
    1125                 :                         {
    1126               0 :                                 const LinkProbe *probe =
    1127               0 :                                     (const LinkProbe *) octets;
    1128               0 :                                 tipc_net_addr_t addr = ntohl(probe->cfg.addr);
    1129               0 :                                 uint maxLinks = ntohl(probe->lowestLinkCount);
    1130               0 :                                 struct tipc_media *b =
    1131               0 :                                     media_find_by_name(probe->cfg.media_name);
    1132               0 :                                 LinkRequest *r =
    1133               0 :                                     &manager.zones[tipc_zone_id(addr)].node_req;
    1134               0 :                                 Link *link = 0;
    1135                 : 
    1136               0 :                                 retval = 0;
    1137               0 :                                 if (r->addr == probe->cfg.addr)
    1138               0 :                                         break;  /* Duplicate request. Drop. */
    1139               0 :                                 link = link_find(addr, b->id);
    1140               0 :                                 if ((!link)
    1141                 :                                     && ((!r->addr)
    1142                 :                                         && (zone_linkcount(tipc_zone_id(addr))
    1143                 :                                             <= maxLinks))) {
    1144                 :                                         memcpy(&manager.
    1145                 :                                                zones[tipc_zone_id(addr)].
    1146                 :                                                parked, probe,
    1147               0 :                                                sizeof (LinkProbe));
    1148               0 :                                         manager_requestLink(r, addr, b,
    1149                 :                                                             &probe->cfg.
    1150                 :                                                             media_addr);
    1151               0 :                                         break;
    1152                 :                                 }
    1153               0 :                                 manager_forwardLinkProbe(probe);
    1154               0 :                                 break;
    1155                 :                         }
    1156                 :                 case TIPC_LINK_REQUEST_REJECTED:
    1157                 :                         {
    1158               0 :                                 LinkRequest *r =
    1159               0 :                                     &manager.zones[tipc_zone_id(orig)].node_req;
    1160               0 :                                 if (r->addr == orig) {
    1161               0 :                                         manager_cancelLinkReq(r);
    1162               0 :                                         manager_forwardLinkProbe(&manager.
    1163                 :                                                                  zones
    1164                 :                                                                  [tipc_zone_id
    1165                 :                                                                   (orig)].
    1166                 :                                                                  parked);
    1167                 :                                 }
    1168               0 :                                 retval = 0;
    1169               0 :                                 break;
    1170                 :                         }
    1171                 :                 case TIPC_LINK_REQUEST_ACCEPTED:
    1172                 :                         {
    1173               0 :                                 LinkRequest *r =
    1174               0 :                                     &manager.zones[tipc_zone_id(orig)].node_req;
    1175               0 :                                 if (r->addr == orig) {
    1176               0 :                                         media_add_link(r->media, orig,
    1177                 :                                                        (struct tipc_media_addr
    1178                 :                                                         *)
    1179                 :                                                        &r->media_addr);
    1180               0 :                                         manager_cancelLinkReq(r);
    1181               0 :                                         manager_forwardLinkProbe(&manager.
    1182                 :                                                                  zones
    1183                 :                                                                  [tipc_zone_id
    1184                 :                                                                   (orig)].
    1185                 :                                                                  parked);
    1186                 :                                 }
    1187               0 :                                 retval = 0;
    1188               0 :                                 break;
    1189                 :                         }
    1190                 :                 case TIPC_DROP_LINK_REQUEST:
    1191                 :                         {
    1192               0 :                                 LinkRequest *r =
    1193               0 :                                     &manager.zones[tipc_zone_id(orig)].node_req;
    1194               0 :                                 if (r->addr == orig) {
    1195               0 :                                         manager_cancelLinkReq(r);
    1196                 :                                 }
    1197               0 :                                 retval = 0;
    1198               0 :                                 break;
    1199                 :                         }
    1200                 :                 case TIPC_CHECK_LINK_COUNT:
    1201                 :                         {
    1202               0 :                                 if (zone_linkcount(tipc_zone_id(orig)) > 2) {
    1203                 :                                         /* Both endpoints have > 2 inter zone links => common link can be removed: */
    1204               0 :                                         Link *link = link_select(orig, 0);
    1205                 : 
    1206               0 :                                         if (link) {
    1207               0 :                                                 info("Removing extra link to %u-%u-%u.\n", TIPC_ADDR_SPLIT(orig));
    1208               0 :                                                 link_reset(link);
    1209                 :                                         }
    1210                 :                                 }
    1211               0 :                                 retval = 0;
    1212                 :                                 break;
    1213                 :                         }
    1214                 :                 default:{
    1215                 :                         }
    1216                 :                 }
    1217                 :         }
    1218              24 :         if (retval)
    1219               0 :                 __tipc_send2port(manager.portid, origin, 5u, rmsg);
    1220              72 :         spin_unlock_bh(&tipc_big_lock);
    1221                 : }
    1222                 : 
    1223                 : int
    1224                 : tipc_manager_start(void)
    1225               1 : {
    1226               1 :         memset(&manager, 0, sizeof (manager));
    1227               1 :         __tipc_attach(&manager.userid, 0, 0);
    1228                 :         {
    1229               1 :                 tipc_createport_argv a = { 0, tipc_non_rejectable, 0, 0,
    1230                 :                         manager_named_message_event, 0, 0
    1231               1 :                 };
    1232               1 :                 tipc_portname_sequence seq = { 0, tipc_my_addr, tipc_my_addr };
    1233               1 :                 tipc_portname_sequence iseq = { 1, TIPC_GET_MEDIA_INFO,
    1234                 :                         TIPC_CHECK_LINK_COUNT
    1235               1 :                 };
    1236                 : 
    1237               1 :                 __tipc_createport(manager.userid, &a, &manager.portid);
    1238               1 :                 __tipc_publish_namesequence(manager.portid, 1u, tipc_zone_scope,
    1239                 :                                             &seq);
    1240               1 :                 __tipc_publish_namesequence(manager.portid, 1u, tipc_zone_scope,
    1241                 :                                             &iseq);
    1242                 : 
    1243                 :                 /* Prepare the manager connection port */
    1244               1 :                 a.connected_message_cb = manager_connection_message_event;
    1245               1 :                 __tipc_createport(manager.userid, &a, &manager.conn_portid);
    1246                 :         }
    1247                 :         {
    1248               1 :                 uint dummy;
    1249               1 :                 tipc_network_subscription_argv s =
    1250               1 :                     { 0, 0, manager_network_event };
    1251               1 :                 __tipc_subscribe2network(manager.userid, &s, &manager.subscrid,
    1252                 :                                          &dummy);
    1253                 :         }
    1254                 :         {
    1255               1 :                 TipcLinkSubscribeArgv argv = { 0, manager_link_event };
    1256                 : 
    1257               1 :                 tipc_linkSubscribe(&argv);
    1258                 :         }
    1259               1 :         return 0;
    1260                 : }
    1261                 : 
    1262                 : void
    1263                 : tipc_manager_stop(void)
    1264               0 : {
    1265               0 :         if (manager.userid)
    1266               0 :                 __tipc_detach(manager.userid);
    1267                 : }

Generated by: LTP GCOV extension version 1.1