Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: add 128-bit node identifier

We add a 128-bit node identity, as an alternative to the currently used
32-bit node address.

For the sake of compatibility and to minimize message header changes
we retain the existing 32-bit address field. When not set explicitly by
the user, this field will be filled with a hash value generated from the
much longer node identity, and be used as a shorthand value for the
latter.

We permit either the address or the identity to be set by configuration,
but not both, so when the address value is set by a legacy user the
corresponding 128-bit node identity is generated based on the that value.

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>

authored by

Jon Maloy and committed by
David S. Miller
d50ccc2d 23fd3eac

+148 -56
+2
include/uapi/linux/tipc_netlink.h
··· 169 169 TIPC_NLA_NET_UNSPEC, 170 170 TIPC_NLA_NET_ID, /* u32 */ 171 171 TIPC_NLA_NET_ADDR, /* u32 */ 172 + TIPC_NLA_NET_NODEID, /* u64 */ 173 + TIPC_NLA_NET_NODEID_W1, /* u64 */ 172 174 173 175 __TIPC_NLA_NET_MAX, 174 176 TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
+67 -14
net/tipc/addr.c
··· 1 1 /* 2 2 * net/tipc/addr.c: TIPC address utility routines 3 3 * 4 - * Copyright (c) 2000-2006, Ericsson AB 4 + * Copyright (c) 2000-2006, 2018, Ericsson AB 5 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems 6 6 * All rights reserved. 7 7 * ··· 34 34 * POSSIBILITY OF SUCH DAMAGE. 35 35 */ 36 36 37 - #include <linux/kernel.h> 38 37 #include "addr.h" 39 38 #include "core.h" 40 - 41 - /** 42 - * in_own_node - test for node inclusion; <0.0.0> always matches 43 - */ 44 - int in_own_node(struct net *net, u32 addr) 45 - { 46 - return addr == tipc_own_addr(net) || !addr; 47 - } 48 39 49 40 bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr) 50 41 { ··· 52 61 return false; 53 62 } 54 63 55 - char *tipc_addr_string_fill(char *string, u32 addr) 64 + void tipc_set_node_id(struct net *net, u8 *id) 56 65 { 57 - snprintf(string, 16, "<%u.%u.%u>", 58 - tipc_zone(addr), tipc_cluster(addr), tipc_node(addr)); 59 - return string; 66 + struct tipc_net *tn = tipc_net(net); 67 + u32 *tmp = (u32 *)id; 68 + 69 + memcpy(tn->node_id, id, NODE_ID_LEN); 70 + tipc_nodeid2string(tn->node_id_string, id); 71 + tn->node_addr = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]; 72 + pr_info("Own node identity %s, cluster identity %u\n", 73 + tipc_own_id_string(net), tn->net_id); 74 + } 75 + 76 + void tipc_set_node_addr(struct net *net, u32 addr) 77 + { 78 + struct tipc_net *tn = tipc_net(net); 79 + u8 node_id[NODE_ID_LEN] = {0,}; 80 + 81 + tn->node_addr = addr; 82 + if (!tipc_own_id(net)) { 83 + sprintf(node_id, "%x", addr); 84 + tipc_set_node_id(net, node_id); 85 + } 86 + pr_info("32-bit node address hash set to %x\n", addr); 87 + } 88 + 89 + char *tipc_nodeid2string(char *str, u8 *id) 90 + { 91 + int i; 92 + u8 c; 93 + 94 + /* Already a string ? */ 95 + for (i = 0; i < NODE_ID_LEN; i++) { 96 + c = id[i]; 97 + if (c >= '0' && c <= '9') 98 + continue; 99 + if (c >= 'A' && c <= 'Z') 100 + continue; 101 + if (c >= 'a' && c <= 'z') 102 + continue; 103 + if (c == '.') 104 + continue; 105 + if (c == ':') 106 + continue; 107 + if (c == '_') 108 + continue; 109 + if (c == '-') 110 + continue; 111 + if (c == '@') 112 + continue; 113 + if (c != 0) 114 + break; 115 + } 116 + if (i == NODE_ID_LEN) { 117 + memcpy(str, id, NODE_ID_LEN); 118 + str[NODE_ID_LEN] = 0; 119 + return str; 120 + } 121 + 122 + /* Translate to hex string */ 123 + for (i = 0; i < NODE_ID_LEN; i++) 124 + sprintf(&str[2 * i], "%02x", id[i]); 125 + 126 + /* Strip off trailing zeroes */ 127 + for (i = NODE_ID_STR_LEN - 2; str[i] == '0'; i--) 128 + str[i] = 0; 129 + 130 + return str; 60 131 }
+23 -5
net/tipc/addr.h
··· 1 1 /* 2 2 * net/tipc/addr.h: Include file for TIPC address utility routines 3 3 * 4 - * Copyright (c) 2000-2006, Ericsson AB 4 + * Copyright (c) 2000-2006, 2018, Ericsson AB 5 5 * Copyright (c) 2004-2005, Wind River Systems 6 6 * All rights reserved. 7 7 * ··· 45 45 46 46 static inline u32 tipc_own_addr(struct net *net) 47 47 { 48 + return tipc_net(net)->node_addr; 49 + } 50 + 51 + static inline u8 *tipc_own_id(struct net *net) 52 + { 48 53 struct tipc_net *tn = tipc_net(net); 49 54 50 - return tn->own_addr; 55 + if (!strlen(tn->node_id_string)) 56 + return NULL; 57 + return tn->node_id; 58 + } 59 + 60 + static inline char *tipc_own_id_string(struct net *net) 61 + { 62 + return tipc_net(net)->node_id_string; 51 63 } 52 64 53 65 static inline u32 tipc_cluster_mask(u32 addr) ··· 77 65 return sc != TIPC_NODE_SCOPE ? 0 : tipc_own_addr(net); 78 66 } 79 67 80 - u32 tipc_own_addr(struct net *net); 81 - int in_own_node(struct net *net, u32 addr); 68 + static inline int in_own_node(struct net *net, u32 addr) 69 + { 70 + return addr == tipc_own_addr(net) || !addr; 71 + } 72 + 82 73 bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr); 83 - char *tipc_addr_string_fill(char *string, u32 addr); 74 + void tipc_set_node_id(struct net *net, u8 *id); 75 + void tipc_set_node_addr(struct net *net, u32 addr); 76 + char *tipc_nodeid2string(char *str, u8 *id); 77 + u32 tipc_node_id2hash(u8 *id128); 84 78 85 79 #endif
+3 -1
net/tipc/core.c
··· 56 56 int err; 57 57 58 58 tn->net_id = 4711; 59 - tn->own_addr = 0; 59 + tn->node_addr = 0; 60 + memset(tn->node_id, 0, sizeof(tn->node_id)); 61 + memset(tn->node_id_string, 0, sizeof(tn->node_id_string)); 60 62 tn->mon_threshold = TIPC_DEF_MON_THRESHOLD; 61 63 get_random_bytes(&tn->random, sizeof(int)); 62 64 INIT_LIST_HEAD(&tn->node_list);
+5 -1
net/tipc/core.h
··· 72 72 #define NODE_HTABLE_SIZE 512 73 73 #define MAX_BEARERS 3 74 74 #define TIPC_DEF_MON_THRESHOLD 32 75 + #define NODE_ID_LEN 16 76 + #define NODE_ID_STR_LEN (NODE_ID_LEN * 2 + 1) 75 77 76 78 extern unsigned int tipc_net_id __read_mostly; 77 79 extern int sysctl_tipc_rmem[3] __read_mostly; 78 80 extern int sysctl_tipc_named_timeout __read_mostly; 79 81 80 82 struct tipc_net { 81 - u32 own_addr; 83 + u8 node_id[NODE_ID_LEN]; 84 + u32 node_addr; 85 + char node_id_string[NODE_ID_STR_LEN]; 82 86 int net_id; 83 87 int random; 84 88 bool legacy_addr_format;
+1 -3
net/tipc/discover.c
··· 118 118 static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr, 119 119 struct tipc_media_addr *media_addr) 120 120 { 121 - char node_addr_str[16]; 122 121 char media_addr_str[64]; 123 122 124 - tipc_addr_string_fill(node_addr_str, node_addr); 125 123 tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str), 126 124 media_addr); 127 - pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, 125 + pr_warn("Duplicate %x using %s seen on <%s>\n", node_addr, 128 126 media_addr_str, b->name); 129 127 } 130 128
+5 -1
net/tipc/link.c
··· 442 442 struct sk_buff_head *namedq, 443 443 struct tipc_link **link) 444 444 { 445 + char *self_str = tipc_own_id_string(net); 445 446 struct tipc_link *l; 446 447 447 448 l = kzalloc(sizeof(*l), GFP_ATOMIC); ··· 452 451 l->session = session; 453 452 454 453 /* Note: peer i/f name is completed by reset/activate message */ 455 - sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer); 454 + if (strlen(self_str) > 16) 455 + sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer); 456 + else 457 + sprintf(l->name, "%s:%s-%x:unknown", self_str, if_name, peer); 456 458 strcpy(l->if_name, if_name); 457 459 l->addr = peer; 458 460 l->peer_caps = peer_caps;
+2 -4
net/tipc/name_distr.c
··· 318 318 { 319 319 struct distr_queue_item *e, *tmp; 320 320 struct tipc_net *tn = net_generic(net, tipc_net_id); 321 - char addr[16]; 322 321 unsigned long now = get_jiffies_64(); 323 322 324 323 list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { ··· 325 326 if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) 326 327 continue; 327 328 } else { 328 - tipc_addr_string_fill(addr, e->node); 329 - pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %s key=%u\n", 329 + pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %x key=%u\n", 330 330 e->dtype, ntohl(e->i.type), 331 331 ntohl(e->i.lower), 332 332 ntohl(e->i.upper), 333 - addr, ntohl(e->i.key)); 333 + e->node, ntohl(e->i.key)); 334 334 } 335 335 list_del(&e->next); 336 336 kfree(e);
+35 -16
net/tipc/net.c
··· 104 104 * - A local spin_lock protecting the queue of subscriber events. 105 105 */ 106 106 107 - int tipc_net_start(struct net *net, u32 addr) 107 + int tipc_net_init(struct net *net, u8 *node_id, u32 addr) 108 108 { 109 - struct tipc_net *tn = tipc_net(net); 110 - char addr_string[16]; 109 + if (tipc_own_id(net)) { 110 + pr_info("Cannot configure node identity twice\n"); 111 + return -1; 112 + } 113 + pr_info("Started in network mode\n"); 111 114 112 - tn->own_addr = addr; 115 + if (node_id) { 116 + tipc_set_node_id(net, node_id); 117 + tipc_net_finalize(net, tipc_own_addr(net)); 118 + } 119 + if (addr) 120 + tipc_net_finalize(net, addr); 121 + return 0; 122 + } 113 123 114 - /* Ensure that the new address is visible before we reinit. */ 124 + void tipc_net_finalize(struct net *net, u32 addr) 125 + { 126 + tipc_set_node_addr(net, addr); 115 127 smp_mb(); 116 - 117 128 tipc_named_reinit(net); 118 129 tipc_sk_reinit(net); 119 - 120 130 tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, 121 131 TIPC_CLUSTER_SCOPE, 0, addr); 122 - 123 - pr_info("Started in network mode\n"); 124 - pr_info("Own node address %s, cluster identity %u\n", 125 - tipc_addr_string_fill(addr_string, addr), 126 - tn->net_id); 127 - return 0; 128 132 } 129 133 130 134 void tipc_net_stop(struct net *net) ··· 150 146 static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg) 151 147 { 152 148 struct tipc_net *tn = net_generic(net, tipc_net_id); 153 - void *hdr; 149 + u64 *w0 = (u64 *)&tn->node_id[0]; 150 + u64 *w1 = (u64 *)&tn->node_id[8]; 154 151 struct nlattr *attrs; 152 + void *hdr; 155 153 156 154 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 157 155 NLM_F_MULTI, TIPC_NL_NET_GET); ··· 166 160 167 161 if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id)) 168 162 goto attr_msg_full; 169 - 163 + if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID, *w0, 0)) 164 + goto attr_msg_full; 165 + if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID_W1, *w1, 0)) 166 + goto attr_msg_full; 170 167 nla_nest_end(msg->skb, attrs); 171 168 genlmsg_end(msg->skb, hdr); 172 169 ··· 221 212 err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX, 222 213 info->attrs[TIPC_NLA_NET], tipc_nl_net_policy, 223 214 info->extack); 215 + 224 216 if (err) 225 217 return err; 226 218 ··· 246 236 if (!addr) 247 237 return -EINVAL; 248 238 tn->legacy_addr_format = true; 249 - tipc_net_start(net, addr); 239 + tipc_net_init(net, NULL, addr); 250 240 } 251 241 242 + if (attrs[TIPC_NLA_NET_NODEID]) { 243 + u8 node_id[NODE_ID_LEN]; 244 + u64 *w0 = (u64 *)&node_id[0]; 245 + u64 *w1 = (u64 *)&node_id[8]; 246 + 247 + *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]); 248 + *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]); 249 + tipc_net_init(net, node_id, 0); 250 + } 252 251 return 0; 253 252 } 254 253
+1 -3
net/tipc/net.h
··· 41 41 42 42 extern const struct nla_policy tipc_nl_net_policy[]; 43 43 44 - int tipc_net_start(struct net *net, u32 addr); 45 - 44 + void tipc_net_finalize(struct net *net, u32 addr); 46 45 void tipc_net_stop(struct net *net); 47 - 48 46 int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); 49 47 int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); 50 48 int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
+2 -6
net/tipc/node.c
··· 883 883 884 884 static void tipc_node_reset_links(struct tipc_node *n) 885 885 { 886 - char addr_string[16]; 887 886 int i; 888 887 889 - pr_warn("Resetting all links to %s\n", 890 - tipc_addr_string_fill(addr_string, n->addr)); 888 + pr_warn("Resetting all links to %x\n", n->addr); 891 889 892 890 for (i = 0; i < MAX_BEARERS; i++) { 893 891 tipc_node_link_down(n, i, false); ··· 1072 1074 static void node_lost_contact(struct tipc_node *n, 1073 1075 struct sk_buff_head *inputq) 1074 1076 { 1075 - char addr_string[16]; 1076 1077 struct tipc_sock_conn *conn, *safe; 1077 1078 struct tipc_link *l; 1078 1079 struct list_head *conns = &n->conn_sks; 1079 1080 struct sk_buff *skb; 1080 1081 uint i; 1081 1082 1082 - pr_debug("Lost contact with %s\n", 1083 - tipc_addr_string_fill(addr_string, n->addr)); 1083 + pr_debug("Lost contact with %x\n", n->addr); 1084 1084 1085 1085 /* Clean up broadcast state */ 1086 1086 tipc_bcast_remove_peer(n->net, n->bc_entry.link);
+2 -2
net/tipc/node.h
··· 49 49 TIPC_BCAST_STATE_NACK = (1 << 2), 50 50 TIPC_BLOCK_FLOWCTL = (1 << 3), 51 51 TIPC_BCAST_RCAST = (1 << 4), 52 - TIPC_NODE_ID32 = (1 << 5) 52 + TIPC_NODE_ID128 = (1 << 5) 53 53 }; 54 54 55 55 #define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \ 56 56 TIPC_BCAST_STATE_NACK | \ 57 57 TIPC_BCAST_RCAST | \ 58 58 TIPC_BLOCK_FLOWCTL | \ 59 - TIPC_NODE_ID32) 59 + TIPC_NODE_ID128) 60 60 #define INVALID_BEARER_ID -1 61 61 62 62 void tipc_node_stop(struct net *net);