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 "node.h"
0039 #include "discover.h"
0040
0041
0042 #define TIPC_DISC_INIT msecs_to_jiffies(125)
0043
0044 #define TIPC_DISC_FAST msecs_to_jiffies(1000)
0045
0046 #define TIPC_DISC_SLOW msecs_to_jiffies(60000)
0047
0048 #define TIPC_DISC_INACTIVE 0xffffffff
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 struct tipc_discoverer {
0063 u32 bearer_id;
0064 struct tipc_media_addr dest;
0065 struct net *net;
0066 u32 domain;
0067 int num_nodes;
0068 spinlock_t lock;
0069 struct sk_buff *skb;
0070 struct timer_list timer;
0071 unsigned long timer_intv;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081 static void tipc_disc_init_msg(struct net *net, struct sk_buff *skb,
0082 u32 mtyp, struct tipc_bearer *b)
0083 {
0084 struct tipc_net *tn = tipc_net(net);
0085 u32 dest_domain = b->domain;
0086 struct tipc_msg *hdr;
0087
0088 hdr = buf_msg(skb);
0089 tipc_msg_init(tn->trial_addr, hdr, LINK_CONFIG, mtyp,
0090 MAX_H_SIZE, dest_domain);
0091 msg_set_size(hdr, MAX_H_SIZE + NODE_ID_LEN);
0092 msg_set_non_seq(hdr, 1);
0093 msg_set_node_sig(hdr, tn->random);
0094 msg_set_node_capabilities(hdr, TIPC_NODE_CAPABILITIES);
0095 msg_set_dest_domain(hdr, dest_domain);
0096 msg_set_bc_netid(hdr, tn->net_id);
0097 b->media->addr2msg(msg_media_addr(hdr), &b->addr);
0098 msg_set_peer_net_hash(hdr, tipc_net_hash_mixes(net, tn->random));
0099 msg_set_node_id(hdr, tipc_own_id(net));
0100 }
0101
0102 static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst,
0103 u32 src, u32 sugg_addr,
0104 struct tipc_media_addr *maddr,
0105 struct tipc_bearer *b)
0106 {
0107 struct tipc_msg *hdr;
0108 struct sk_buff *skb;
0109
0110 skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC);
0111 if (!skb)
0112 return;
0113 hdr = buf_msg(skb);
0114 tipc_disc_init_msg(net, skb, mtyp, b);
0115 msg_set_sugg_node_addr(hdr, sugg_addr);
0116 msg_set_dest_domain(hdr, dst);
0117 tipc_bearer_xmit_skb(net, b->identity, skb, maddr);
0118 }
0119
0120
0121
0122
0123
0124
0125
0126 static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr,
0127 struct tipc_media_addr *media_addr)
0128 {
0129 char media_addr_str[64];
0130
0131 tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str),
0132 media_addr);
0133 pr_warn("Duplicate %x using %s seen on <%s>\n", node_addr,
0134 media_addr_str, b->name);
0135 }
0136
0137
0138
0139
0140
0141 static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
0142 struct tipc_media_addr *maddr,
0143 struct tipc_bearer *b,
0144 u32 dst, u32 src,
0145 u32 sugg_addr,
0146 u8 *peer_id,
0147 int mtyp)
0148 {
0149 struct net *net = d->net;
0150 struct tipc_net *tn = tipc_net(net);
0151 bool trial = time_before(jiffies, tn->addr_trial_end);
0152 u32 self = tipc_own_addr(net);
0153
0154 if (mtyp == DSC_TRIAL_FAIL_MSG) {
0155 if (!trial)
0156 return true;
0157
0158
0159 if (dst != tn->trial_addr)
0160 return true;
0161
0162
0163 tn->trial_addr = sugg_addr;
0164 msg_set_prevnode(buf_msg(d->skb), sugg_addr);
0165 tn->addr_trial_end = jiffies + msecs_to_jiffies(1000);
0166 return true;
0167 }
0168
0169
0170 if (!trial && !self) {
0171 schedule_work(&tn->work);
0172 msg_set_prevnode(buf_msg(d->skb), tn->trial_addr);
0173 msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
0174 }
0175
0176
0177 if (mtyp != DSC_TRIAL_MSG)
0178 return trial;
0179
0180 sugg_addr = tipc_node_try_addr(net, peer_id, src);
0181 if (sugg_addr)
0182 tipc_disc_msg_xmit(net, DSC_TRIAL_FAIL_MSG, src,
0183 self, sugg_addr, maddr, b);
0184 return true;
0185 }
0186
0187
0188
0189
0190
0191
0192
0193 void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
0194 struct tipc_bearer *b)
0195 {
0196 struct tipc_net *tn = tipc_net(net);
0197 struct tipc_msg *hdr = buf_msg(skb);
0198 u32 pnet_hash = msg_peer_net_hash(hdr);
0199 u16 caps = msg_node_capabilities(hdr);
0200 bool legacy = tn->legacy_addr_format;
0201 u32 sugg = msg_sugg_node_addr(hdr);
0202 u32 signature = msg_node_sig(hdr);
0203 u8 peer_id[NODE_ID_LEN] = {0,};
0204 u32 dst = msg_dest_domain(hdr);
0205 u32 net_id = msg_bc_netid(hdr);
0206 struct tipc_media_addr maddr;
0207 u32 src = msg_prevnode(hdr);
0208 u32 mtyp = msg_type(hdr);
0209 bool dupl_addr = false;
0210 bool respond = false;
0211 u32 self;
0212 int err;
0213
0214 skb_linearize(skb);
0215 hdr = buf_msg(skb);
0216
0217 if (caps & TIPC_NODE_ID128)
0218 memcpy(peer_id, msg_node_id(hdr), NODE_ID_LEN);
0219 else
0220 sprintf(peer_id, "%x", src);
0221
0222 err = b->media->msg2addr(b, &maddr, msg_media_addr(hdr));
0223 kfree_skb(skb);
0224 if (err || maddr.broadcast) {
0225 pr_warn_ratelimited("Rcv corrupt discovery message\n");
0226 return;
0227 }
0228
0229 if (!memcmp(&maddr, &b->addr, sizeof(maddr)))
0230 return;
0231 if (net_id != tn->net_id)
0232 return;
0233 if (tipc_disc_addr_trial_msg(b->disc, &maddr, b, dst,
0234 src, sugg, peer_id, mtyp))
0235 return;
0236 self = tipc_own_addr(net);
0237
0238
0239 if (in_own_node(net, src)) {
0240 disc_dupl_alert(b, self, &maddr);
0241 return;
0242 }
0243 if (!tipc_in_scope(legacy, dst, self))
0244 return;
0245 if (!tipc_in_scope(legacy, b->domain, src))
0246 return;
0247 tipc_node_check_dest(net, src, peer_id, b, caps, signature, pnet_hash,
0248 &maddr, &respond, &dupl_addr);
0249 if (dupl_addr)
0250 disc_dupl_alert(b, src, &maddr);
0251 if (!respond)
0252 return;
0253 if (mtyp != DSC_REQ_MSG)
0254 return;
0255 tipc_disc_msg_xmit(net, DSC_RESP_MSG, src, self, 0, &maddr, b);
0256 }
0257
0258
0259
0260 void tipc_disc_add_dest(struct tipc_discoverer *d)
0261 {
0262 spin_lock_bh(&d->lock);
0263 d->num_nodes++;
0264 spin_unlock_bh(&d->lock);
0265 }
0266
0267
0268
0269 void tipc_disc_remove_dest(struct tipc_discoverer *d)
0270 {
0271 int intv, num;
0272
0273 spin_lock_bh(&d->lock);
0274 d->num_nodes--;
0275 num = d->num_nodes;
0276 intv = d->timer_intv;
0277 if (!num && (intv == TIPC_DISC_INACTIVE || intv > TIPC_DISC_FAST)) {
0278 d->timer_intv = TIPC_DISC_INIT;
0279 mod_timer(&d->timer, jiffies + d->timer_intv);
0280 }
0281 spin_unlock_bh(&d->lock);
0282 }
0283
0284
0285
0286
0287
0288
0289
0290 static void tipc_disc_timeout(struct timer_list *t)
0291 {
0292 struct tipc_discoverer *d = from_timer(d, t, timer);
0293 struct tipc_net *tn = tipc_net(d->net);
0294 struct tipc_media_addr maddr;
0295 struct sk_buff *skb = NULL;
0296 struct net *net = d->net;
0297 u32 bearer_id;
0298
0299 spin_lock_bh(&d->lock);
0300
0301
0302 if (tipc_node(d->domain) && d->num_nodes) {
0303 d->timer_intv = TIPC_DISC_INACTIVE;
0304 goto exit;
0305 }
0306
0307
0308 if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) {
0309 mod_timer(&d->timer, jiffies + TIPC_DISC_INIT);
0310 spin_unlock_bh(&d->lock);
0311 schedule_work(&tn->work);
0312 return;
0313 }
0314
0315
0316 if (time_before(jiffies, tn->addr_trial_end)) {
0317 d->timer_intv = TIPC_DISC_INIT;
0318 } else {
0319 d->timer_intv *= 2;
0320 if (d->num_nodes && d->timer_intv > TIPC_DISC_SLOW)
0321 d->timer_intv = TIPC_DISC_SLOW;
0322 else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST)
0323 d->timer_intv = TIPC_DISC_FAST;
0324 msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
0325 msg_set_prevnode(buf_msg(d->skb), tn->trial_addr);
0326 }
0327
0328 mod_timer(&d->timer, jiffies + d->timer_intv);
0329 memcpy(&maddr, &d->dest, sizeof(maddr));
0330 skb = skb_clone(d->skb, GFP_ATOMIC);
0331 bearer_id = d->bearer_id;
0332 exit:
0333 spin_unlock_bh(&d->lock);
0334 if (skb)
0335 tipc_bearer_xmit_skb(net, bearer_id, skb, &maddr);
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 int tipc_disc_create(struct net *net, struct tipc_bearer *b,
0348 struct tipc_media_addr *dest, struct sk_buff **skb)
0349 {
0350 struct tipc_net *tn = tipc_net(net);
0351 struct tipc_discoverer *d;
0352
0353 d = kmalloc(sizeof(*d), GFP_ATOMIC);
0354 if (!d)
0355 return -ENOMEM;
0356 d->skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC);
0357 if (!d->skb) {
0358 kfree(d);
0359 return -ENOMEM;
0360 }
0361 tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b);
0362
0363
0364 if (!tipc_own_addr(net)) {
0365 tn->addr_trial_end = jiffies + msecs_to_jiffies(1000);
0366 msg_set_type(buf_msg(d->skb), DSC_TRIAL_MSG);
0367 }
0368 memcpy(&d->dest, dest, sizeof(*dest));
0369 d->net = net;
0370 d->bearer_id = b->identity;
0371 d->domain = b->domain;
0372 d->num_nodes = 0;
0373 d->timer_intv = TIPC_DISC_INIT;
0374 spin_lock_init(&d->lock);
0375 timer_setup(&d->timer, tipc_disc_timeout, 0);
0376 mod_timer(&d->timer, jiffies + d->timer_intv);
0377 b->disc = d;
0378 *skb = skb_clone(d->skb, GFP_ATOMIC);
0379 return 0;
0380 }
0381
0382
0383
0384
0385
0386 void tipc_disc_delete(struct tipc_discoverer *d)
0387 {
0388 del_timer_sync(&d->timer);
0389 kfree_skb(d->skb);
0390 kfree(d);
0391 }
0392
0393
0394
0395
0396
0397
0398 void tipc_disc_reset(struct net *net, struct tipc_bearer *b)
0399 {
0400 struct tipc_discoverer *d = b->disc;
0401 struct tipc_media_addr maddr;
0402 struct sk_buff *skb;
0403
0404 spin_lock_bh(&d->lock);
0405 tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b);
0406 d->net = net;
0407 d->bearer_id = b->identity;
0408 d->domain = b->domain;
0409 d->num_nodes = 0;
0410 d->timer_intv = TIPC_DISC_INIT;
0411 memcpy(&maddr, &d->dest, sizeof(maddr));
0412 mod_timer(&d->timer, jiffies + d->timer_intv);
0413 skb = skb_clone(d->skb, GFP_ATOMIC);
0414 spin_unlock_bh(&d->lock);
0415 if (skb)
0416 tipc_bearer_xmit_skb(net, b->identity, skb, &maddr);
0417 }