net.c (1f901d59a5489e4dc7fdd339808d89b89f35483e) | net.c (37922ea4a3105176357c8d565a9d982c4a08714a) |
---|---|
1/* 2 * net/tipc/net.c: TIPC network routing code 3 * 4 * Copyright (c) 1995-2006, 2014, Ericsson AB 5 * Copyright (c) 2005, 2010-2011, Wind River Systems 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 90 unchanged lines hidden (view full) --- 99 * - There is one local spin_lock per sub_sequence, which can be seen 100 * as a sub-domain to the tipc_nametbl_lock domain. It is used only 101 * for translation operations, and is needed because a translation 102 * steps the root of the 'publication' linked list between each lookup. 103 * This is always used within the scope of a tipc_nametbl_lock(read). 104 * - A local spin_lock protecting the queue of subscriber events. 105*/ 106 | 1/* 2 * net/tipc/net.c: TIPC network routing code 3 * 4 * Copyright (c) 1995-2006, 2014, Ericsson AB 5 * Copyright (c) 2005, 2010-2011, Wind River Systems 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 90 unchanged lines hidden (view full) --- 99 * - There is one local spin_lock per sub_sequence, which can be seen 100 * as a sub-domain to the tipc_nametbl_lock domain. It is used only 101 * for translation operations, and is needed because a translation 102 * steps the root of the 'publication' linked list between each lookup. 103 * This is always used within the scope of a tipc_nametbl_lock(read). 104 * - A local spin_lock protecting the queue of subscriber events. 105*/ 106 |
107int tipc_net_start(struct net *net, u32 addr) | 107int tipc_net_init(struct net *net, u8 *node_id, u32 addr) |
108{ | 108{ |
109 struct tipc_net *tn = net_generic(net, tipc_net_id); 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 if (addr) 118 tipc_net_finalize(net, addr); 119 return 0; 120} |
113 | 121 |
114 /* Ensure that the new address is visible before we reinit. */ | 122void tipc_net_finalize(struct net *net, u32 addr) 123{ 124 tipc_set_node_addr(net, addr); |
115 smp_mb(); | 125 smp_mb(); |
116 | |
117 tipc_named_reinit(net); 118 tipc_sk_reinit(net); | 126 tipc_named_reinit(net); 127 tipc_sk_reinit(net); |
119 120 tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr, 121 TIPC_ZONE_SCOPE, 0, tn->own_addr); 122 123 pr_info("Started in network mode\n"); 124 pr_info("Own node address %s, network identity %u\n", 125 tipc_addr_string_fill(addr_string, tn->own_addr), 126 tn->net_id); 127 return 0; | 128 tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, 129 TIPC_CLUSTER_SCOPE, 0, addr); |
128} 129 130void tipc_net_stop(struct net *net) 131{ | 130} 131 132void tipc_net_stop(struct net *net) 133{ |
132 struct tipc_net *tn = net_generic(net, tipc_net_id); | 134 u32 self = tipc_own_addr(net); |
133 | 135 |
134 if (!tn->own_addr) | 136 if (!self) |
135 return; 136 | 137 return; 138 |
137 tipc_nametbl_withdraw(net, TIPC_CFG_SRV, tn->own_addr, 0, 138 tn->own_addr); | 139 tipc_nametbl_withdraw(net, TIPC_CFG_SRV, self, self, self); |
139 rtnl_lock(); 140 tipc_bearer_stop(net); 141 tipc_node_stop(net); 142 rtnl_unlock(); 143 144 pr_info("Left network mode\n"); 145} 146 147static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg) 148{ 149 struct tipc_net *tn = net_generic(net, tipc_net_id); | 140 rtnl_lock(); 141 tipc_bearer_stop(net); 142 tipc_node_stop(net); 143 rtnl_unlock(); 144 145 pr_info("Left network mode\n"); 146} 147 148static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg) 149{ 150 struct tipc_net *tn = net_generic(net, tipc_net_id); |
150 void *hdr; | 151 u64 *w0 = (u64 *)&tn->node_id[0]; 152 u64 *w1 = (u64 *)&tn->node_id[8]; |
151 struct nlattr *attrs; | 153 struct nlattr *attrs; |
154 void *hdr; |
|
152 153 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 154 NLM_F_MULTI, TIPC_NL_NET_GET); 155 if (!hdr) 156 return -EMSGSIZE; 157 158 attrs = nla_nest_start(msg->skb, TIPC_NLA_NET); 159 if (!attrs) 160 goto msg_full; 161 162 if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id)) 163 goto attr_msg_full; | 155 156 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 157 NLM_F_MULTI, TIPC_NL_NET_GET); 158 if (!hdr) 159 return -EMSGSIZE; 160 161 attrs = nla_nest_start(msg->skb, TIPC_NLA_NET); 162 if (!attrs) 163 goto msg_full; 164 165 if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id)) 166 goto attr_msg_full; |
164 | 167 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID, *w0, 0)) 168 goto attr_msg_full; 169 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID_W1, *w1, 0)) 170 goto attr_msg_full; |
165 nla_nest_end(msg->skb, attrs); 166 genlmsg_end(msg->skb, hdr); 167 168 return 0; 169 170attr_msg_full: 171 nla_nest_cancel(msg->skb, attrs); 172msg_full: --- 24 unchanged lines hidden (view full) --- 197out: 198 cb->args[0] = done; 199 200 return skb->len; 201} 202 203int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) 204{ | 171 nla_nest_end(msg->skb, attrs); 172 genlmsg_end(msg->skb, hdr); 173 174 return 0; 175 176attr_msg_full: 177 nla_nest_cancel(msg->skb, attrs); 178msg_full: --- 24 unchanged lines hidden (view full) --- 203out: 204 cb->args[0] = done; 205 206 return skb->len; 207} 208 209int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) 210{ |
205 struct net *net = sock_net(skb->sk); 206 struct tipc_net *tn = net_generic(net, tipc_net_id); | |
207 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; | 211 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; |
212 struct net *net = sock_net(skb->sk); 213 struct tipc_net *tn = tipc_net(net); |
|
208 int err; 209 210 if (!info->attrs[TIPC_NLA_NET]) 211 return -EINVAL; 212 213 err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX, 214 info->attrs[TIPC_NLA_NET], tipc_nl_net_policy, 215 info->extack); | 214 int err; 215 216 if (!info->attrs[TIPC_NLA_NET]) 217 return -EINVAL; 218 219 err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX, 220 info->attrs[TIPC_NLA_NET], tipc_nl_net_policy, 221 info->extack); |
222 |
|
216 if (err) 217 return err; 218 | 223 if (err) 224 return err; 225 |
226 /* Can't change net id once TIPC has joined a network */ 227 if (tipc_own_addr(net)) 228 return -EPERM; 229 |
|
219 if (attrs[TIPC_NLA_NET_ID]) { 220 u32 val; 221 | 230 if (attrs[TIPC_NLA_NET_ID]) { 231 u32 val; 232 |
222 /* Can't change net id once TIPC has joined a network */ 223 if (tn->own_addr) 224 return -EPERM; 225 | |
226 val = nla_get_u32(attrs[TIPC_NLA_NET_ID]); 227 if (val < 1 || val > 9999) 228 return -EINVAL; 229 230 tn->net_id = val; 231 } 232 233 if (attrs[TIPC_NLA_NET_ADDR]) { 234 u32 addr; 235 | 233 val = nla_get_u32(attrs[TIPC_NLA_NET_ID]); 234 if (val < 1 || val > 9999) 235 return -EINVAL; 236 237 tn->net_id = val; 238 } 239 240 if (attrs[TIPC_NLA_NET_ADDR]) { 241 u32 addr; 242 |
236 /* Can't change net addr once TIPC has joined a network */ 237 if (tn->own_addr) 238 return -EPERM; 239 | |
240 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); | 243 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); |
241 if (!tipc_addr_node_valid(addr)) | 244 if (!addr) |
242 return -EINVAL; | 245 return -EINVAL; |
243 244 tipc_net_start(net, addr); | 246 tn->legacy_addr_format = true; 247 tipc_net_init(net, NULL, addr); |
245 } 246 | 248 } 249 |
250 if (attrs[TIPC_NLA_NET_NODEID]) { 251 u8 node_id[NODE_ID_LEN]; 252 u64 *w0 = (u64 *)&node_id[0]; 253 u64 *w1 = (u64 *)&node_id[8]; 254 255 *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]); 256 *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]); 257 tipc_net_init(net, node_id, 0); 258 } |
|
247 return 0; 248} 249 250int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) 251{ 252 int err; 253 254 rtnl_lock(); 255 err = __tipc_nl_net_set(skb, info); 256 rtnl_unlock(); 257 258 return err; 259} | 259 return 0; 260} 261 262int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) 263{ 264 int err; 265 266 rtnl_lock(); 267 err = __tipc_nl_net_set(skb, info); 268 rtnl_unlock(); 269 270 return err; 271} |