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}