Commit b89afb11 authored by Jon Maloy's avatar Jon Maloy Committed by David S. Miller

tipc: allow closest-first lookup algorithm when legacy address is configured

The removal of an internal structure of the node address has an unwanted
side effect.
- Currently, if a user is sending an anycast message with destination
  domain 0, the tipc_namebl_translate() function will use the 'closest-
  first' algorithm to first look for a node local destination, and only
  when no such is found, will it resort to the cluster global 'round-
  robin' lookup algorithm.
- Current users can get around this, and enforce unconditional use of
  global round-robin by indicating a destination as Z.0.0 or Z.C.0.
- This option disappears when we make the node address flat, since the
  lookup algorithm has no way of recognizing this case. So, as long as
  there are node local destinations, the algorithm will always select
  one of those, and there is nothing the sender can do to change this.

We solve this by eliminating the 'closest-first' option, which was never
a good idea anyway, for non-legacy users, but only for those. To
distinguish between legacy users and non-legacy users we introduce a new
flag 'legacy_addr_format' in struct tipc_core, to be set when the user
configures a legacy-style Z.C.N node address. Hence, when a legacy user
indicates a zero lookup domain 'closest-first' is selected, and in all
other cases we use 'round-robin'.
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 20263641
...@@ -48,15 +48,17 @@ int in_own_node(struct net *net, u32 addr) ...@@ -48,15 +48,17 @@ int in_own_node(struct net *net, u32 addr)
return (addr == tn->own_addr) || !addr; return (addr == tn->own_addr) || !addr;
} }
int tipc_in_scope(u32 domain, u32 addr) bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
{ {
if (!domain || (domain == addr)) if (!domain || (domain == addr))
return 1; return true;
if (!legacy_format)
return false;
if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */ if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
return 1; return true;
if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */ if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */
return 1; return true;
return 0; return false;
} }
char *tipc_addr_string_fill(char *string, u32 addr) char *tipc_addr_string_fill(char *string, u32 addr)
......
...@@ -67,7 +67,7 @@ static inline int tipc_scope2node(struct net *net, int sc) ...@@ -67,7 +67,7 @@ static inline int tipc_scope2node(struct net *net, int sc)
u32 tipc_own_addr(struct net *net); u32 tipc_own_addr(struct net *net);
int in_own_node(struct net *net, u32 addr); int in_own_node(struct net *net, u32 addr);
int tipc_in_scope(u32 domain, u32 addr); bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr);
char *tipc_addr_string_fill(char *string, u32 addr); char *tipc_addr_string_fill(char *string, u32 addr);
#endif #endif
/* /*
* net/tipc/core.h: Include file for TIPC global declarations * net/tipc/core.h: Include file for TIPC global declarations
* *
* Copyright (c) 2005-2006, 2013 Ericsson AB * Copyright (c) 2005-2006, 2013-2018 Ericsson AB
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems * Copyright (c) 2005-2007, 2010-2013, Wind River Systems
* All rights reserved. * All rights reserved.
* *
...@@ -81,6 +81,7 @@ struct tipc_net { ...@@ -81,6 +81,7 @@ struct tipc_net {
u32 own_addr; u32 own_addr;
int net_id; int net_id;
int random; int random;
bool legacy_addr_format;
/* Node table and node list */ /* Node table and node list */
spinlock_t node_list_lock; spinlock_t node_list_lock;
......
...@@ -139,6 +139,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb, ...@@ -139,6 +139,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
struct tipc_net *tn = tipc_net(net); struct tipc_net *tn = tipc_net(net);
struct tipc_msg *hdr = buf_msg(skb); struct tipc_msg *hdr = buf_msg(skb);
u16 caps = msg_node_capabilities(hdr); u16 caps = msg_node_capabilities(hdr);
bool legacy = tn->legacy_addr_format;
u32 signature = msg_node_sig(hdr); u32 signature = msg_node_sig(hdr);
u32 dst = msg_dest_domain(hdr); u32 dst = msg_dest_domain(hdr);
u32 net_id = msg_bc_netid(hdr); u32 net_id = msg_bc_netid(hdr);
...@@ -165,13 +166,11 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb, ...@@ -165,13 +166,11 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
disc_dupl_alert(b, self, &maddr); disc_dupl_alert(b, self, &maddr);
return; return;
} }
/* Domain filter only works if both peers use legacy address format */ if (!tipc_in_scope(legacy, dst, self))
if (b->domain) {
if (!tipc_in_scope(dst, self))
return; return;
if (!tipc_in_scope(b->domain, src)) if (!tipc_in_scope(legacy, b->domain, src))
return; return;
}
tipc_node_check_dest(net, src, b, caps, signature, tipc_node_check_dest(net, src, b, caps, signature,
&maddr, &respond, &dupl_addr); &maddr, &respond, &dupl_addr);
if (dupl_addr) if (dupl_addr)
......
...@@ -499,7 +499,9 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, ...@@ -499,7 +499,9 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
u32 *destnode) u32 *destnode)
{ {
struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_net *tn = tipc_net(net);
bool legacy = tn->legacy_addr_format;
u32 self = tipc_own_addr(net);
struct sub_seq *sseq; struct sub_seq *sseq;
struct name_info *info; struct name_info *info;
struct publication *publ; struct publication *publ;
...@@ -507,7 +509,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, ...@@ -507,7 +509,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
u32 port = 0; u32 port = 0;
u32 node = 0; u32 node = 0;
if (!tipc_in_scope(*destnode, tn->own_addr)) if (!tipc_in_scope(legacy, *destnode, self))
return 0; return 0;
rcu_read_lock(); rcu_read_lock();
...@@ -521,7 +523,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, ...@@ -521,7 +523,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
info = sseq->info; info = sseq->info;
/* Closest-First Algorithm */ /* Closest-First Algorithm */
if (likely(!*destnode)) { if (legacy && !*destnode) {
if (!list_empty(&info->local_publ)) { if (!list_empty(&info->local_publ)) {
publ = list_first_entry(&info->local_publ, publ = list_first_entry(&info->local_publ,
struct publication, struct publication,
......
...@@ -240,7 +240,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) ...@@ -240,7 +240,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
if (!addr) if (!addr)
return -EINVAL; return -EINVAL;
tn->legacy_addr_format = true;
tipc_net_start(net, addr); tipc_net_start(net, addr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment