aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2018-03-22 15:42:47 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-23 13:12:18 -0400
commit2026364149db36c6a2c0c8cae8362fe9a7f954dd (patch)
tree267dc296fc385f53a8bd9537c9ac8193ea4b5663 /net/tipc
parentb39e465e56ec38ca64b4c0affeb6411eb0ed7267 (diff)
tipc: remove restrictions on node address values
Nominally, TIPC organizes network nodes into a three-level network hierarchy consisting of the levels 'zone', 'cluster' and 'node'. This hierarchy is reflected in the node address format, - it is sub-divided into an 8-bit zone id, and 12 bit cluster id, and a 12-bit node id. However, the 'zone' and 'cluster' levels have in reality never been fully implemented,and never will be. The result of this has been that the first 20 bits the node identity structure have been wasted, and the usable node identity range within a cluster has been limited to 12 bits. This is starting to become a problem. In the following commits, we will need to be able to connect between nodes which are using the whole 32-bit value space of the node address. We therefore remove the restrictions on which values can be assigned to node identity, -it is from now on only a 32-bit integer with no assumed internal structure. Isolation between clusters is now achieved only by setting different values for the 'network id' field used during neighbor discovery, in practice leading to the latter becoming the new cluster identity. The rules for accepting discovery requests/responses from neighboring nodes now become: - If the user is using legacy address format on both peers, reception of discovery messages is subject to the legacy lookup domain check in addition to the cluster id check. - Otherwise, the discovery request/response is always accepted, provided both peers have the same network id. This secures backwards compatibility for users who have been using zone or cluster identities as cluster separators, instead of the intended 'network id'. Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/addr.c50
-rw-r--r--net/tipc/addr.h11
-rw-r--r--net/tipc/bearer.c27
-rw-r--r--net/tipc/discover.c15
-rw-r--r--net/tipc/link.c6
-rw-r--r--net/tipc/net.c4
-rw-r--r--net/tipc/node.c8
-rw-r--r--net/tipc/node.h5
8 files changed, 21 insertions, 105 deletions
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 97cd857d7f43..dfc31a730ca5 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -39,21 +39,6 @@
39#include "core.h" 39#include "core.h"
40 40
41/** 41/**
42 * in_own_cluster - test for cluster inclusion; <0.0.0> always matches
43 */
44int in_own_cluster(struct net *net, u32 addr)
45{
46 return in_own_cluster_exact(net, addr) || !addr;
47}
48
49int in_own_cluster_exact(struct net *net, u32 addr)
50{
51 struct tipc_net *tn = net_generic(net, tipc_net_id);
52
53 return !((addr ^ tn->own_addr) >> 12);
54}
55
56/**
57 * in_own_node - test for node inclusion; <0.0.0> always matches 42 * in_own_node - test for node inclusion; <0.0.0> always matches
58 */ 43 */
59int in_own_node(struct net *net, u32 addr) 44int in_own_node(struct net *net, u32 addr)
@@ -63,46 +48,13 @@ int in_own_node(struct net *net, u32 addr)
63 return (addr == tn->own_addr) || !addr; 48 return (addr == tn->own_addr) || !addr;
64} 49}
65 50
66/**
67 * tipc_addr_domain_valid - validates a network domain address
68 *
69 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
70 * where Z, C, and N are non-zero.
71 *
72 * Returns 1 if domain address is valid, otherwise 0
73 */
74int tipc_addr_domain_valid(u32 addr)
75{
76 u32 n = tipc_node(addr);
77 u32 c = tipc_cluster(addr);
78 u32 z = tipc_zone(addr);
79
80 if (n && (!z || !c))
81 return 0;
82 if (c && !z)
83 return 0;
84 return 1;
85}
86
87/**
88 * tipc_addr_node_valid - validates a proposed network address for this node
89 *
90 * Accepts <Z.C.N>, where Z, C, and N are non-zero.
91 *
92 * Returns 1 if address can be used, otherwise 0
93 */
94int tipc_addr_node_valid(u32 addr)
95{
96 return tipc_addr_domain_valid(addr) && tipc_node(addr);
97}
98
99int tipc_in_scope(u32 domain, u32 addr) 51int tipc_in_scope(u32 domain, u32 addr)
100{ 52{
101 if (!domain || (domain == addr)) 53 if (!domain || (domain == addr))
102 return 1; 54 return 1;
103 if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */ 55 if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
104 return 1; 56 return 1;
105 if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */ 57 if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */
106 return 1; 58 return 1;
107 return 0; 59 return 0;
108} 60}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 2ecf5a5d40dd..5ffde51b0e68 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -50,11 +50,6 @@ static inline u32 tipc_own_addr(struct net *net)
50 return tn->own_addr; 50 return tn->own_addr;
51} 51}
52 52
53static inline u32 tipc_zone_mask(u32 addr)
54{
55 return addr & TIPC_ZONE_MASK;
56}
57
58static inline u32 tipc_cluster_mask(u32 addr) 53static inline u32 tipc_cluster_mask(u32 addr)
59{ 54{
60 return addr & TIPC_ZONE_CLUSTER_MASK; 55 return addr & TIPC_ZONE_CLUSTER_MASK;
@@ -71,14 +66,8 @@ static inline int tipc_scope2node(struct net *net, int sc)
71} 66}
72 67
73u32 tipc_own_addr(struct net *net); 68u32 tipc_own_addr(struct net *net);
74int in_own_cluster(struct net *net, u32 addr);
75int in_own_cluster_exact(struct net *net, u32 addr);
76int in_own_node(struct net *net, u32 addr); 69int in_own_node(struct net *net, u32 addr);
77u32 addr_domain(struct net *net, u32 sc);
78int tipc_addr_domain_valid(u32);
79int tipc_addr_node_valid(u32 addr);
80int tipc_in_scope(u32 domain, u32 addr); 70int tipc_in_scope(u32 domain, u32 addr);
81int tipc_addr_scope(u32 domain);
82char *tipc_addr_string_fill(char *string, u32 addr); 71char *tipc_addr_string_fill(char *string, u32 addr);
83 72
84#endif 73#endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 76340b9e4851..a71f31879cb3 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -240,7 +240,6 @@ static int tipc_enable_bearer(struct net *net, const char *name,
240 struct tipc_bearer *b; 240 struct tipc_bearer *b;
241 struct tipc_media *m; 241 struct tipc_media *m;
242 struct sk_buff *skb; 242 struct sk_buff *skb;
243 char addr_string[16];
244 int bearer_id = 0; 243 int bearer_id = 0;
245 int res = -EINVAL; 244 int res = -EINVAL;
246 char *errstr = ""; 245 char *errstr = "";
@@ -256,21 +255,6 @@ static int tipc_enable_bearer(struct net *net, const char *name,
256 goto rejected; 255 goto rejected;
257 } 256 }
258 257
259 if (tipc_addr_domain_valid(disc_domain) && disc_domain != self) {
260 if (tipc_in_scope(disc_domain, self)) {
261 /* Accept any node in own cluster */
262 disc_domain = self & TIPC_ZONE_CLUSTER_MASK;
263 res = 0;
264 } else if (in_own_cluster_exact(net, disc_domain)) {
265 /* Accept specified node in own cluster */
266 res = 0;
267 }
268 }
269 if (res) {
270 errstr = "illegal discovery domain";
271 goto rejected;
272 }
273
274 if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) { 258 if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
275 errstr = "illegal priority"; 259 errstr = "illegal priority";
276 goto rejected; 260 goto rejected;
@@ -354,12 +338,11 @@ static int tipc_enable_bearer(struct net *net, const char *name,
354 return -ENOMEM; 338 return -ENOMEM;
355 } 339 }
356 340
357 tipc_addr_string_fill(addr_string, disc_domain); 341 pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
358 pr_info("Enabled bearer <%s>, discovery scope %s, priority %u\n", 342
359 name, addr_string, prio);
360 return res; 343 return res;
361rejected: 344rejected:
362 pr_warn("Bearer <%s> rejected, %s\n", name, errstr); 345 pr_warn("Enabling of bearer <%s> rejected, %s\n", name, errstr);
363 return res; 346 return res;
364} 347}
365 348
@@ -865,12 +848,10 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
865 char *bearer; 848 char *bearer;
866 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; 849 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
867 struct net *net = sock_net(skb->sk); 850 struct net *net = sock_net(skb->sk);
868 struct tipc_net *tn = net_generic(net, tipc_net_id); 851 u32 domain = 0;
869 u32 domain;
870 u32 prio; 852 u32 prio;
871 853
872 prio = TIPC_MEDIA_LINK_PRI; 854 prio = TIPC_MEDIA_LINK_PRI;
873 domain = tn->own_addr & TIPC_ZONE_CLUSTER_MASK;
874 855
875 if (!info->attrs[TIPC_NLA_BEARER]) 856 if (!info->attrs[TIPC_NLA_BEARER])
876 return -EINVAL; 857 return -EINVAL;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 09f75558d353..669af125b3de 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -161,18 +161,17 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
161 return; 161 return;
162 if (net_id != tn->net_id) 162 if (net_id != tn->net_id)
163 return; 163 return;
164 if (!tipc_addr_domain_valid(dst))
165 return;
166 if (!tipc_addr_node_valid(src))
167 return;
168 if (in_own_node(net, src)) { 164 if (in_own_node(net, src)) {
169 disc_dupl_alert(b, self, &maddr); 165 disc_dupl_alert(b, self, &maddr);
170 return; 166 return;
171 } 167 }
172 if (!tipc_in_scope(dst, self)) 168 /* Domain filter only works if both peers use legacy address format */
173 return; 169 if (b->domain) {
174 if (!tipc_in_scope(b->domain, src)) 170 if (!tipc_in_scope(dst, self))
175 return; 171 return;
172 if (!tipc_in_scope(b->domain, src))
173 return;
174 }
176 tipc_node_check_dest(net, src, b, caps, signature, 175 tipc_node_check_dest(net, src, b, caps, signature,
177 &maddr, &respond, &dupl_addr); 176 &maddr, &respond, &dupl_addr);
178 if (dupl_addr) 177 if (dupl_addr)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 3c230466804d..86fde005ea47 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -434,7 +434,7 @@ char *tipc_link_name(struct tipc_link *l)
434 */ 434 */
435bool tipc_link_create(struct net *net, char *if_name, int bearer_id, 435bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
436 int tolerance, char net_plane, u32 mtu, int priority, 436 int tolerance, char net_plane, u32 mtu, int priority,
437 int window, u32 session, u32 ownnode, u32 peer, 437 int window, u32 session, u32 self, u32 peer,
438 u16 peer_caps, 438 u16 peer_caps,
439 struct tipc_link *bc_sndlink, 439 struct tipc_link *bc_sndlink,
440 struct tipc_link *bc_rcvlink, 440 struct tipc_link *bc_rcvlink,
@@ -451,9 +451,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
451 l->session = session; 451 l->session = session;
452 452
453 /* Note: peer i/f name is completed by reset/activate message */ 453 /* Note: peer i/f name is completed by reset/activate message */
454 sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 454 sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer);
455 tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
456 if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
457 strcpy(l->if_name, if_name); 455 strcpy(l->if_name, if_name);
458 l->addr = peer; 456 l->addr = peer;
459 l->peer_caps = peer_caps; 457 l->peer_caps = peer_caps;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 5c4c4405b78e..a074f285e6ea 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -121,7 +121,7 @@ int tipc_net_start(struct net *net, u32 addr)
121 TIPC_CLUSTER_SCOPE, 0, tn->own_addr); 121 TIPC_CLUSTER_SCOPE, 0, tn->own_addr);
122 122
123 pr_info("Started in network mode\n"); 123 pr_info("Started in network mode\n");
124 pr_info("Own node address %s, network identity %u\n", 124 pr_info("Own node address %s, cluster identity %u\n",
125 tipc_addr_string_fill(addr_string, tn->own_addr), 125 tipc_addr_string_fill(addr_string, tn->own_addr),
126 tn->net_id); 126 tn->net_id);
127 return 0; 127 return 0;
@@ -238,7 +238,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
238 return -EPERM; 238 return -EPERM;
239 239
240 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); 240 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
241 if (!tipc_addr_node_valid(addr)) 241 if (!addr)
242 return -EINVAL; 242 return -EINVAL;
243 243
244 tipc_net_start(net, addr); 244 tipc_net_start(net, addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 389193d7cf67..8a4b04933ecc 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -233,9 +233,6 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
233 struct tipc_node *node; 233 struct tipc_node *node;
234 unsigned int thash = tipc_hashfn(addr); 234 unsigned int thash = tipc_hashfn(addr);
235 235
236 if (unlikely(!in_own_cluster_exact(net, addr)))
237 return NULL;
238
239 rcu_read_lock(); 236 rcu_read_lock();
240 hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) { 237 hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
241 if (node->addr != addr) 238 if (node->addr != addr)
@@ -836,10 +833,9 @@ void tipc_node_check_dest(struct net *net, u32 onode,
836 833
837 /* Now create new link if not already existing */ 834 /* Now create new link if not already existing */
838 if (!l) { 835 if (!l) {
839 if (n->link_cnt == 2) { 836 if (n->link_cnt == 2)
840 pr_warn("Cannot establish 3rd link to %x\n", n->addr);
841 goto exit; 837 goto exit;
842 } 838
843 if_name = strchr(b->name, ':') + 1; 839 if_name = strchr(b->name, ':') + 1;
844 if (!tipc_link_create(net, if_name, b->identity, b->tolerance, 840 if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
845 b->net_plane, b->mtu, b->priority, 841 b->net_plane, b->mtu, b->priority,
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 4ce5e3a185c0..5fb38cf0bb5c 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -49,13 +49,14 @@ enum {
49 TIPC_BCAST_STATE_NACK = (1 << 2), 49 TIPC_BCAST_STATE_NACK = (1 << 2),
50 TIPC_BLOCK_FLOWCTL = (1 << 3), 50 TIPC_BLOCK_FLOWCTL = (1 << 3),
51 TIPC_BCAST_RCAST = (1 << 4), 51 TIPC_BCAST_RCAST = (1 << 4),
52 TIPC_MCAST_GROUPS = (1 << 5) 52 TIPC_NODE_ID32 = (1 << 5)
53}; 53};
54 54
55#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \ 55#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
56 TIPC_BCAST_STATE_NACK | \ 56 TIPC_BCAST_STATE_NACK | \
57 TIPC_BCAST_RCAST | \ 57 TIPC_BCAST_RCAST | \
58 TIPC_BLOCK_FLOWCTL) 58 TIPC_BLOCK_FLOWCTL | \
59 TIPC_NODE_ID32)
59#define INVALID_BEARER_ID -1 60#define INVALID_BEARER_ID -1
60 61
61void tipc_node_stop(struct net *net); 62void tipc_node_stop(struct net *net);