linux/net/tipc/zone.c
<<
>>
Prefs
   1/*
   2 * net/tipc/zone.c: TIPC zone management routines
   3 *
   4 * Copyright (c) 2000-2006, Ericsson AB
   5 * Copyright (c) 2005, Wind River Systems
   6 * All rights reserved.
   7 *
   8 * Redistribution and use in source and binary forms, with or without
   9 * modification, are permitted provided that the following conditions are met:
  10 *
  11 * 1. Redistributions of source code must retain the above copyright
  12 *    notice, this list of conditions and the following disclaimer.
  13 * 2. Redistributions in binary form must reproduce the above copyright
  14 *    notice, this list of conditions and the following disclaimer in the
  15 *    documentation and/or other materials provided with the distribution.
  16 * 3. Neither the names of the copyright holders nor the names of its
  17 *    contributors may be used to endorse or promote products derived from
  18 *    this software without specific prior written permission.
  19 *
  20 * Alternatively, this software may be distributed under the terms of the
  21 * GNU General Public License ("GPL") version 2 as published by the Free
  22 * Software Foundation.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34 * POSSIBILITY OF SUCH DAMAGE.
  35 */
  36
  37#include "core.h"
  38#include "zone.h"
  39#include "net.h"
  40#include "addr.h"
  41#include "node_subscr.h"
  42#include "cluster.h"
  43#include "node.h"
  44
  45struct _zone *tipc_zone_create(u32 addr)
  46{
  47        struct _zone *z_ptr;
  48        u32 z_num;
  49
  50        if (!tipc_addr_domain_valid(addr)) {
  51                err("Zone creation failed, invalid domain 0x%x\n", addr);
  52                return NULL;
  53        }
  54
  55        z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC);
  56        if (!z_ptr) {
  57                warn("Zone creation failed, insufficient memory\n");
  58                return NULL;
  59        }
  60
  61        z_num = tipc_zone(addr);
  62        z_ptr->addr = tipc_addr(z_num, 0, 0);
  63        tipc_net.zones[z_num] = z_ptr;
  64        return z_ptr;
  65}
  66
  67void tipc_zone_delete(struct _zone *z_ptr)
  68{
  69        u32 c_num;
  70
  71        if (!z_ptr)
  72                return;
  73        for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
  74                tipc_cltr_delete(z_ptr->clusters[c_num]);
  75        }
  76        kfree(z_ptr);
  77}
  78
  79void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
  80{
  81        u32 c_num = tipc_cluster(c_ptr->addr);
  82
  83        assert(c_ptr->addr);
  84        assert(c_num <= tipc_max_clusters);
  85        assert(z_ptr->clusters[c_num] == NULL);
  86        z_ptr->clusters[c_num] = c_ptr;
  87}
  88
  89void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router)
  90{
  91        u32 c_num;
  92
  93        for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
  94                if (z_ptr->clusters[c_num]) {
  95                        tipc_cltr_remove_as_router(z_ptr->clusters[c_num],
  96                                                   router);
  97                }
  98        }
  99}
 100
 101void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest)
 102{
 103        u32 c_num;
 104
 105        for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
 106                if (z_ptr->clusters[c_num]) {
 107                        if (in_own_cluster(z_ptr->addr))
 108                                continue;
 109                        tipc_cltr_send_ext_routes(z_ptr->clusters[c_num], dest);
 110                }
 111        }
 112}
 113
 114struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
 115{
 116        struct cluster *c_ptr;
 117        struct tipc_node *n_ptr;
 118        u32 c_num;
 119
 120        if (!z_ptr)
 121                return NULL;
 122        c_ptr = z_ptr->clusters[tipc_cluster(addr)];
 123        if (!c_ptr)
 124                return NULL;
 125        n_ptr = tipc_cltr_select_node(c_ptr, ref);
 126        if (n_ptr)
 127                return n_ptr;
 128
 129        /* Links to any other clusters within this zone ? */
 130        for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
 131                c_ptr = z_ptr->clusters[c_num];
 132                if (!c_ptr)
 133                        return NULL;
 134                n_ptr = tipc_cltr_select_node(c_ptr, ref);
 135                if (n_ptr)
 136                        return n_ptr;
 137        }
 138        return NULL;
 139}
 140
 141u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
 142{
 143        struct cluster *c_ptr;
 144        u32 c_num;
 145        u32 router;
 146
 147        if (!z_ptr)
 148                return 0;
 149        c_ptr = z_ptr->clusters[tipc_cluster(addr)];
 150        router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
 151        if (router)
 152                return router;
 153
 154        /* Links to any other clusters within the zone? */
 155        for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
 156                c_ptr = z_ptr->clusters[c_num];
 157                router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
 158                if (router)
 159                        return router;
 160        }
 161        return 0;
 162}
 163
 164
 165u32 tipc_zone_next_node(u32 addr)
 166{
 167        struct cluster *c_ptr = tipc_cltr_find(addr);
 168
 169        if (c_ptr)
 170                return tipc_cltr_next_node(c_ptr, addr);
 171        return 0;
 172}
 173
 174