tipc: make node number calculation reproducible

The 32-bit node number, aka node hash or node address, is calculated
based on the 128-bit node identity when it is not set explicitly by
the user. In future commits we will need to perform this hash operation
on peer nodes while feeling safe that we obtain the same result.

We do this by interpreting the initial hash as a network byte order
number. Whenever we need to use the number locally on a node
we must therefore translate it to host byte order to obtain an
architecure independent result.

Furthermore, given the context where we use this number, we must not
allow it to be zero unless the node identity also is zero. Hence, in
the rare cases when the xor-ed hash value may end up as zero we replace
it with a fix number, knowing that the code anyway is capable of
handling hash collisions.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jon Maloy 2020-11-25 13:29:14 -05:00 committed by Jakub Kicinski
parent 60c102eede
commit 5f75e0a0e9
3 changed files with 16 additions and 4 deletions

View File

@ -55,12 +55,11 @@ bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
void tipc_set_node_id(struct net *net, u8 *id) void tipc_set_node_id(struct net *net, u8 *id)
{ {
struct tipc_net *tn = tipc_net(net); struct tipc_net *tn = tipc_net(net);
u32 *tmp = (u32 *)id;
memcpy(tn->node_id, id, NODE_ID_LEN); memcpy(tn->node_id, id, NODE_ID_LEN);
tipc_nodeid2string(tn->node_id_string, id); tipc_nodeid2string(tn->node_id_string, id);
tn->trial_addr = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]; tn->trial_addr = hash128to32(id);
pr_info("Own node identity %s, cluster identity %u\n", pr_info("Node identity %s, cluster identity %u\n",
tipc_own_id_string(net), tn->net_id); tipc_own_id_string(net), tn->net_id);
} }
@ -76,7 +75,7 @@ void tipc_set_node_addr(struct net *net, u32 addr)
} }
tn->trial_addr = addr; tn->trial_addr = addr;
tn->addr_trial_end = jiffies; tn->addr_trial_end = jiffies;
pr_info("32-bit node address hash set to %x\n", addr); pr_info("Node number set to %u\n", addr);
} }
char *tipc_nodeid2string(char *str, u8 *id) char *tipc_nodeid2string(char *str, u8 *id)

View File

@ -3,6 +3,7 @@
* *
* Copyright (c) 2000-2006, 2018, Ericsson AB * Copyright (c) 2000-2006, 2018, Ericsson AB
* Copyright (c) 2004-2005, Wind River Systems * Copyright (c) 2004-2005, Wind River Systems
* Copyright (c) 2020, Red Hat Inc
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -3,6 +3,7 @@
* *
* Copyright (c) 2005-2006, 2013-2018 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
* Copyright (c) 2020, Red Hat Inc
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -210,6 +211,17 @@ static inline u32 tipc_net_hash_mixes(struct net *net, int tn_rand)
return net_hash_mix(&init_net) ^ net_hash_mix(net) ^ tn_rand; return net_hash_mix(&init_net) ^ net_hash_mix(net) ^ tn_rand;
} }
static inline u32 hash128to32(char *bytes)
{
__be32 *tmp = (__be32 *)bytes;
u32 res;
res = ntohl(tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]);
if (likely(res))
return res;
return ntohl(tmp[0] | tmp[1] | tmp[2] | tmp[3]);
}
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
int tipc_register_sysctl(void); int tipc_register_sysctl(void);
void tipc_unregister_sysctl(void); void tipc_unregister_sysctl(void);