0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include "core.h"
0038 #include "net.h"
0039 #include "name_distr.h"
0040 #include "subscr.h"
0041 #include "socket.h"
0042 #include "node.h"
0043 #include "bcast.h"
0044 #include "link.h"
0045 #include "netlink.h"
0046 #include "monitor.h"
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 static void tipc_net_finalize(struct net *net, u32 addr);
0110
0111 int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
0112 {
0113 if (tipc_own_id(net)) {
0114 pr_info("Cannot configure node identity twice\n");
0115 return -1;
0116 }
0117 pr_info("Started in network mode\n");
0118
0119 if (node_id)
0120 tipc_set_node_id(net, node_id);
0121 if (addr)
0122 tipc_net_finalize(net, addr);
0123 return 0;
0124 }
0125
0126 static void tipc_net_finalize(struct net *net, u32 addr)
0127 {
0128 struct tipc_net *tn = tipc_net(net);
0129 struct tipc_socket_addr sk = {0, addr};
0130 struct tipc_uaddr ua;
0131
0132 tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,
0133 TIPC_NODE_STATE, addr, addr);
0134
0135 if (cmpxchg(&tn->node_addr, 0, addr))
0136 return;
0137 tipc_set_node_addr(net, addr);
0138 tipc_named_reinit(net);
0139 tipc_sk_reinit(net);
0140 tipc_mon_reinit_self(net);
0141 tipc_nametbl_publish(net, &ua, &sk, addr);
0142 }
0143
0144 void tipc_net_finalize_work(struct work_struct *work)
0145 {
0146 struct tipc_net *tn = container_of(work, struct tipc_net, work);
0147
0148 tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
0149 }
0150
0151 void tipc_net_stop(struct net *net)
0152 {
0153 if (!tipc_own_id(net))
0154 return;
0155
0156 rtnl_lock();
0157 tipc_bearer_stop(net);
0158 tipc_node_stop(net);
0159 rtnl_unlock();
0160
0161 pr_info("Left network mode\n");
0162 }
0163
0164 static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
0165 {
0166 struct tipc_net *tn = net_generic(net, tipc_net_id);
0167 u64 *w0 = (u64 *)&tn->node_id[0];
0168 u64 *w1 = (u64 *)&tn->node_id[8];
0169 struct nlattr *attrs;
0170 void *hdr;
0171
0172 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
0173 NLM_F_MULTI, TIPC_NL_NET_GET);
0174 if (!hdr)
0175 return -EMSGSIZE;
0176
0177 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_NET);
0178 if (!attrs)
0179 goto msg_full;
0180
0181 if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id))
0182 goto attr_msg_full;
0183 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID, *w0, 0))
0184 goto attr_msg_full;
0185 if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID_W1, *w1, 0))
0186 goto attr_msg_full;
0187 nla_nest_end(msg->skb, attrs);
0188 genlmsg_end(msg->skb, hdr);
0189
0190 return 0;
0191
0192 attr_msg_full:
0193 nla_nest_cancel(msg->skb, attrs);
0194 msg_full:
0195 genlmsg_cancel(msg->skb, hdr);
0196
0197 return -EMSGSIZE;
0198 }
0199
0200 int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
0201 {
0202 struct net *net = sock_net(skb->sk);
0203 int err;
0204 int done = cb->args[0];
0205 struct tipc_nl_msg msg;
0206
0207 if (done)
0208 return 0;
0209
0210 msg.skb = skb;
0211 msg.portid = NETLINK_CB(cb->skb).portid;
0212 msg.seq = cb->nlh->nlmsg_seq;
0213
0214 err = __tipc_nl_add_net(net, &msg);
0215 if (err)
0216 goto out;
0217
0218 done = 1;
0219 out:
0220 cb->args[0] = done;
0221
0222 return skb->len;
0223 }
0224
0225 int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
0226 {
0227 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
0228 struct net *net = sock_net(skb->sk);
0229 struct tipc_net *tn = tipc_net(net);
0230 int err;
0231
0232 if (!info->attrs[TIPC_NLA_NET])
0233 return -EINVAL;
0234
0235 err = nla_parse_nested_deprecated(attrs, TIPC_NLA_NET_MAX,
0236 info->attrs[TIPC_NLA_NET],
0237 tipc_nl_net_policy, info->extack);
0238
0239 if (err)
0240 return err;
0241
0242
0243 if (tipc_own_addr(net))
0244 return -EPERM;
0245
0246 if (attrs[TIPC_NLA_NET_ID]) {
0247 u32 val;
0248
0249 val = nla_get_u32(attrs[TIPC_NLA_NET_ID]);
0250 if (val < 1 || val > 9999)
0251 return -EINVAL;
0252
0253 tn->net_id = val;
0254 }
0255
0256 if (attrs[TIPC_NLA_NET_ADDR]) {
0257 u32 addr;
0258
0259 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
0260 if (!addr)
0261 return -EINVAL;
0262 tn->legacy_addr_format = true;
0263 tipc_net_init(net, NULL, addr);
0264 }
0265
0266 if (attrs[TIPC_NLA_NET_NODEID]) {
0267 u8 node_id[NODE_ID_LEN];
0268 u64 *w0 = (u64 *)&node_id[0];
0269 u64 *w1 = (u64 *)&node_id[8];
0270
0271 if (!attrs[TIPC_NLA_NET_NODEID_W1])
0272 return -EINVAL;
0273 *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]);
0274 *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
0275 tipc_net_init(net, node_id, 0);
0276 }
0277 return 0;
0278 }
0279
0280 int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
0281 {
0282 int err;
0283
0284 rtnl_lock();
0285 err = __tipc_nl_net_set(skb, info);
0286 rtnl_unlock();
0287
0288 return err;
0289 }
0290
0291 static int __tipc_nl_addr_legacy_get(struct net *net, struct tipc_nl_msg *msg)
0292 {
0293 struct tipc_net *tn = tipc_net(net);
0294 struct nlattr *attrs;
0295 void *hdr;
0296
0297 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
0298 0, TIPC_NL_ADDR_LEGACY_GET);
0299 if (!hdr)
0300 return -EMSGSIZE;
0301
0302 attrs = nla_nest_start(msg->skb, TIPC_NLA_NET);
0303 if (!attrs)
0304 goto msg_full;
0305
0306 if (tn->legacy_addr_format)
0307 if (nla_put_flag(msg->skb, TIPC_NLA_NET_ADDR_LEGACY))
0308 goto attr_msg_full;
0309
0310 nla_nest_end(msg->skb, attrs);
0311 genlmsg_end(msg->skb, hdr);
0312
0313 return 0;
0314
0315 attr_msg_full:
0316 nla_nest_cancel(msg->skb, attrs);
0317 msg_full:
0318 genlmsg_cancel(msg->skb, hdr);
0319
0320 return -EMSGSIZE;
0321 }
0322
0323 int tipc_nl_net_addr_legacy_get(struct sk_buff *skb, struct genl_info *info)
0324 {
0325 struct net *net = sock_net(skb->sk);
0326 struct tipc_nl_msg msg;
0327 struct sk_buff *rep;
0328 int err;
0329
0330 rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
0331 if (!rep)
0332 return -ENOMEM;
0333
0334 msg.skb = rep;
0335 msg.portid = info->snd_portid;
0336 msg.seq = info->snd_seq;
0337
0338 err = __tipc_nl_addr_legacy_get(net, &msg);
0339 if (err) {
0340 nlmsg_free(msg.skb);
0341 return err;
0342 }
0343
0344 return genlmsg_reply(msg.skb, info);
0345 }