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 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 : #ifndef __NET_TIPC_ADDRESS_H_
31 : #define __NET_TIPC_ADDRESS_H_
32 :
33 : #include <net/tipc.h>
34 : #include <linux/types.h>
35 :
36 : /*
37 : * TIPC network address is a 32-bit word and has 3 fields:
38 : * - node id is the first 12-bits
39 : * - cluster id is the middle 12-bits
40 : * - zone id is the high 8-bits
41 : */
42 :
43 : #define TIPC_ZONE_ADDR_BITS 8
44 : #define TIPC_CLUSTER_ADDR_BITS 12
45 : #define TIPC_NODE_ADDR_BITS 12
46 : #define TIPC_ZONE_ADDR_OFFSET (TIPC_NODE_ADDR_BITS\
47 : + TIPC_CLUSTER_ADDR_BITS)
48 : #define TIPC_CLUSTER_ADDR_OFFSET (TIPC_NODE_ADDR_BITS)
49 : #define TIPC_NODE_ADDR_OFFSET 0
50 :
51 : #if defined(CONFIG_TIPC_ZONES)\
52 : && (CONFIG_TIPC_ZONES <= TIPC_ZONE_ADDR_BITS)\
53 : && (CONFIG_TIPC_ZONES > 0)
54 : #define TIPC_ZONE_AMOUNT (1u << CONFIG_TIPC_ZONES)
55 : #else
56 : #error "CONFIG_TIPC_ZONES is not a sane value!"
57 : #endif
58 :
59 : #if defined(CONFIG_TIPC_CLUSTERS)\
60 : && (CONFIG_TIPC_CLUSTERS <= TIPC_CLUSTER_ADDR_BITS)\
61 : && (CONFIG_TIPC_CLUSTERS > 1)
62 : #define TIPC_CLUSTER_AMOUNT (1u << CONFIG_TIPC_CLUSTERS)
63 : #else
64 : #error "CONFIG_TIPC_CLUSTERS is not a sane value!"
65 : #endif
66 :
67 : #if defined(CONFIG_TIPC_NODES)\
68 : && (CONFIG_TIPC_NODES <= TIPC_NODE_ADDR_BITS)\
69 : && (CONFIG_TIPC_NODES > 2)
70 : /*
71 : * Note: half of the node bits are used for Regular Nodes and the
72 : * other half are used for Device Nodes
73 : */
74 : #define TIPC_NODE_AMOUNT (1u << (CONFIG_TIPC_NODES - 1))
75 : #else
76 : #error "CONFIG_TIPC_NODES is not a sane value!"
77 : #endif
78 :
79 : #if (((TIPC_CLUSTER_AMOUNT * TIPC_NODE_AMOUNT) >> 3) > 256)
80 : #define TIPC_NET_HASH_SIZE ((TIPC_CLUSTER_AMOUNT * TIPC_NODE_AMOUNT) >> 3)
81 : #else
82 : #define TIPC_NET_HASH_SIZE 256
83 : #endif
84 :
85 : #define TIPC_ZONE_MAX_ID (TIPC_ZONE_AMOUNT - 1)
86 : #define TIPC_CLUSTER_MAX_ID (TIPC_CLUSTER_AMOUNT - 1)
87 : #define TIPC_NODE_MAX_ID (TIPC_NODE_AMOUNT - 1)
88 : #define TIPC_SLAVE_MAX_ID ((1u << TIPC_NODE_ADDR_BITS) - 1)
89 : #define TIPC_SLAVE_MIN_ID (1u << (TIPC_NODE_ADDR_BITS - 1))
90 :
91 : extern tipc_net_addr_t tipc_my_addr;
92 :
93 : static inline uint
94 : tipc_node_id(tipc_net_addr_t addr)
95 963106 : {
96 481553 : return ((addr >> TIPC_NODE_ADDR_OFFSET) & TIPC_NODE_MAX_ID);
97 : }
98 :
99 : static inline uint
100 : tipc_cluster_id(tipc_net_addr_t addr)
101 963066 : {
102 481533 : return ((addr >> TIPC_CLUSTER_ADDR_OFFSET) & TIPC_CLUSTER_MAX_ID);
103 : }
104 :
105 : static inline uint
106 : tipc_zone_id(tipc_net_addr_t addr)
107 963138 : {
108 481569 : return ((addr >> TIPC_ZONE_ADDR_OFFSET) & TIPC_ZONE_MAX_ID);
109 : }
110 32 :
111 16 : #define TIPC_ADDR_SPLIT(addr) tipc_zone_id(addr),\
112 : tipc_cluster_id(addr),\
113 : tipc_node_id(addr)
114 :
115 : static inline uint
116 : tipc_slave_addr(tipc_net_addr_t addr)
117 48 : {
118 48 : if (tipc_node_id(addr) < TIPC_SLAVE_MIN_ID)
119 : return 0;
120 : return 1;
121 : }
122 :
123 : /* This does not do checking intentionally: */
124 : static inline tipc_net_addr_t
125 : tipc_make_addr(uint zone, uint cluster, uint node)
126 252 : {
127 122 : tipc_net_addr_t addr = 0;
128 :
129 122 : addr |= (node & TIPC_NODE_MAX_ID) << TIPC_NODE_ADDR_OFFSET;
130 122 : addr |= (cluster & TIPC_CLUSTER_MAX_ID) << TIPC_CLUSTER_ADDR_OFFSET;
131 122 : addr |= (zone & TIPC_ZONE_MAX_ID) << TIPC_ZONE_ADDR_OFFSET;
132 : return addr;
133 : }
134 :
135 : /* Following checks if the destination address matches: */
136 : static inline uint
137 : tipc_addr_match(tipc_net_addr_t dest, tipc_net_addr_t addr)
138 68690 : {
139 : /* Obvious cases (0.0.0 or same address): */
140 34345 : if (!dest || (dest == addr))
141 : return 1;
142 : /* check for zone broadcast (x.0.0): */
143 18 : if (dest == (addr && (TIPC_ZONE_MAX_ID << TIPC_ZONE_ADDR_OFFSET)))
144 : return 1;
145 32 : /* check for cluster broadcast (x.y.0): */
146 18 : if (dest == (addr & ((TIPC_ZONE_MAX_ID << TIPC_ZONE_ADDR_OFFSET)
147 : +
148 : (TIPC_CLUSTER_MAX_ID <<
149 : TIPC_CLUSTER_ADDR_OFFSET))))
150 : return 1;
151 : return 0;
152 : }
153 :
154 : static inline uint
155 : tipc_valid_addr(tipc_net_addr_t addr)
156 22 : {
157 11 : tipc_net_addr_t mask = (TIPC_NODE_MAX_ID << TIPC_NODE_ADDR_OFFSET)
158 : + (TIPC_CLUSTER_MAX_ID << TIPC_CLUSTER_ADDR_OFFSET)
159 11 : + (TIPC_ZONE_MAX_ID << TIPC_ZONE_ADDR_OFFSET);
160 :
161 11 : if (addr & ~mask)
162 : return 0;
163 : return 1;
164 : }
165 :
166 : static inline int
167 : tipc_check_addr(uint z, uint c, uint n)
168 24 : {
169 8 : int ret = 0;
170 :
171 8 : if (n != (n & TIPC_NODE_MAX_ID))
172 8 : ret++;
173 8 : if (c != (c & TIPC_CLUSTER_MAX_ID))
174 8 : ret++;
175 8 : if (z != (z & TIPC_ZONE_MAX_ID))
176 8 : ret++;
177 :
178 : return ret;
179 : }
180 : #endif /* __NET_TIPC_ADDRESS_H_ */
|