Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 1 | /* |
| 2 | * net/tipc/discover.c |
YOSHIFUJI Hideaki | c430728 | 2007-02-09 23:25:21 +0900 | [diff] [blame] | 3 | * |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 4 | * Copyright (c) 2003-2006, 2014-2018, Ericsson AB |
Allan Stephens | 2d627b9 | 2011-01-07 13:00:11 -0500 | [diff] [blame] | 5 | * Copyright (c) 2005-2006, 2010-2011, Wind River Systems |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 6 | * All rights reserved. |
| 7 | * |
Per Liden | 9ea1fd3 | 2006-01-11 13:30:43 +0100 | [diff] [blame] | 8 | * Redistribution and use in source and binary forms, with or without |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 9 | * modification, are permitted provided that the following conditions are met: |
| 10 | * |
Per Liden | 9ea1fd3 | 2006-01-11 13:30:43 +0100 | [diff] [blame] | 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. Neither the names of the copyright holders nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived from |
| 18 | * this software without specific prior written permission. |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 19 | * |
Per Liden | 9ea1fd3 | 2006-01-11 13:30:43 +0100 | [diff] [blame] | 20 | * Alternatively, this software may be distributed under the terms of the |
| 21 | * GNU General Public License ("GPL") version 2 as published by the Free |
| 22 | * Software Foundation. |
| 23 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 34 | * POSSIBILITY OF SUCH DAMAGE. |
| 35 | */ |
| 36 | |
| 37 | #include "core.h" |
Jon Paul Maloy | d3a43b9 | 2015-07-16 16:54:20 -0400 | [diff] [blame] | 38 | #include "node.h" |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 39 | #include "discover.h" |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 40 | |
Ying Xue | 2f55c43 | 2015-01-09 15:27:00 +0800 | [diff] [blame] | 41 | /* min delay during bearer start up */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 42 | #define TIPC_DISC_INIT msecs_to_jiffies(125) |
Ying Xue | 2f55c43 | 2015-01-09 15:27:00 +0800 | [diff] [blame] | 43 | /* max delay if bearer has no links */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 44 | #define TIPC_DISC_FAST msecs_to_jiffies(1000) |
Ying Xue | 2f55c43 | 2015-01-09 15:27:00 +0800 | [diff] [blame] | 45 | /* max delay if bearer has links */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 46 | #define TIPC_DISC_SLOW msecs_to_jiffies(60000) |
Ying Xue | 2f55c43 | 2015-01-09 15:27:00 +0800 | [diff] [blame] | 47 | /* indicates no timer in use */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 48 | #define TIPC_DISC_INACTIVE 0xffffffff |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 49 | |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 50 | /** |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 51 | * struct tipc_discoverer - information about an ongoing link setup request |
Ying Xue | 7a2f7d1 | 2014-04-21 10:55:46 +0800 | [diff] [blame] | 52 | * @bearer_id: identity of bearer issuing requests |
Ying Xue | 7f9f95d | 2015-01-09 15:27:06 +0800 | [diff] [blame] | 53 | * @net: network namespace instance |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 54 | * @dest: destination address for request messages |
Ying Xue | 7a2f7d1 | 2014-04-21 10:55:46 +0800 | [diff] [blame] | 55 | * @domain: network domain to which links can be established |
Allan Stephens | 1209966 | 2011-04-21 19:05:25 -0500 | [diff] [blame] | 56 | * @num_nodes: number of nodes currently discovered (i.e. with an active link) |
Ying Xue | f9a2c80 | 2014-01-07 17:02:43 -0500 | [diff] [blame] | 57 | * @lock: spinlock for controlling access to requests |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 58 | * @skb: request message to be (repeatedly) sent |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 59 | * @timer: timer governing period between requests |
| 60 | * @timer_intv: current interval between requests (in ms) |
| 61 | */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 62 | struct tipc_discoverer { |
Ying Xue | 7a2f7d1 | 2014-04-21 10:55:46 +0800 | [diff] [blame] | 63 | u32 bearer_id; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 64 | struct tipc_media_addr dest; |
Ying Xue | 7f9f95d | 2015-01-09 15:27:06 +0800 | [diff] [blame] | 65 | struct net *net; |
Ying Xue | 7a2f7d1 | 2014-04-21 10:55:46 +0800 | [diff] [blame] | 66 | u32 domain; |
Allan Stephens | 1209966 | 2011-04-21 19:05:25 -0500 | [diff] [blame] | 67 | int num_nodes; |
Ying Xue | f9a2c80 | 2014-01-07 17:02:43 -0500 | [diff] [blame] | 68 | spinlock_t lock; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 69 | struct sk_buff *skb; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 70 | struct timer_list timer; |
Ying Xue | 2f55c43 | 2015-01-09 15:27:00 +0800 | [diff] [blame] | 71 | unsigned long timer_intv; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 72 | }; |
| 73 | |
YOSHIFUJI Hideaki | c430728 | 2007-02-09 23:25:21 +0900 | [diff] [blame] | 74 | /** |
Per Liden | 4323add | 2006-01-18 00:38:21 +0100 | [diff] [blame] | 75 | * tipc_disc_init_msg - initialize a link setup message |
Ying Xue | c93d3ba | 2015-01-09 15:27:04 +0800 | [diff] [blame] | 76 | * @net: the applicable net namespace |
Randy Dunlap | 5fcb7d4 | 2020-11-29 10:32:50 -0800 | [diff] [blame] | 77 | * @skb: buffer containing message |
Andrew Lunn | d814120 | 2020-07-13 01:15:14 +0200 | [diff] [blame] | 78 | * @mtyp: message type (request or response) |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 79 | * @b: ptr to bearer issuing message |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 80 | */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 81 | static void tipc_disc_init_msg(struct net *net, struct sk_buff *skb, |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 82 | u32 mtyp, struct tipc_bearer *b) |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 83 | { |
| 84 | struct tipc_net *tn = tipc_net(net); |
| 85 | u32 dest_domain = b->domain; |
| 86 | struct tipc_msg *hdr; |
| 87 | |
| 88 | hdr = buf_msg(skb); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 89 | tipc_msg_init(tn->trial_addr, hdr, LINK_CONFIG, mtyp, |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 90 | MAX_H_SIZE, dest_domain); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 91 | msg_set_size(hdr, MAX_H_SIZE + NODE_ID_LEN); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 92 | msg_set_non_seq(hdr, 1); |
| 93 | msg_set_node_sig(hdr, tn->random); |
| 94 | msg_set_node_capabilities(hdr, TIPC_NODE_CAPABILITIES); |
| 95 | msg_set_dest_domain(hdr, dest_domain); |
| 96 | msg_set_bc_netid(hdr, tn->net_id); |
| 97 | b->media->addr2msg(msg_media_addr(hdr), &b->addr); |
Hoang Le | f73b128 | 2019-10-29 07:51:21 +0700 | [diff] [blame] | 98 | msg_set_peer_net_hash(hdr, tipc_net_hash_mixes(net, tn->random)); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 99 | msg_set_node_id(hdr, tipc_own_id(net)); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 100 | } |
| 101 | |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 102 | static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst, |
| 103 | u32 src, u32 sugg_addr, |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 104 | struct tipc_media_addr *maddr, |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 105 | struct tipc_bearer *b) |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 106 | { |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 107 | struct tipc_msg *hdr; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 108 | struct sk_buff *skb; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 109 | |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 110 | skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 111 | if (!skb) |
| 112 | return; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 113 | hdr = buf_msg(skb); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 114 | tipc_disc_init_msg(net, skb, mtyp, b); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 115 | msg_set_sugg_node_addr(hdr, sugg_addr); |
| 116 | msg_set_dest_domain(hdr, dst); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 117 | tipc_bearer_xmit_skb(net, b->identity, skb, maddr); |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | /** |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 121 | * disc_dupl_alert - issue node address duplication alert |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 122 | * @b: pointer to bearer detecting duplication |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 123 | * @node_addr: duplicated node address |
| 124 | * @media_addr: media address advertised by duplicated node |
| 125 | */ |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 126 | static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr, |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 127 | struct tipc_media_addr *media_addr) |
| 128 | { |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 129 | char media_addr_str[64]; |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 130 | |
Erik Hugne | dc1aed3 | 2012-06-29 00:50:23 -0400 | [diff] [blame] | 131 | tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str), |
| 132 | media_addr); |
Jon Maloy | d50ccc2 | 2018-03-22 20:42:50 +0100 | [diff] [blame] | 133 | pr_warn("Duplicate %x using %s seen on <%s>\n", node_addr, |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 134 | media_addr_str, b->name); |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 135 | } |
| 136 | |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 137 | /* tipc_disc_addr_trial(): - handle an address uniqueness trial from peer |
Jon Maloy | e415577 | 2018-07-06 20:10:04 +0200 | [diff] [blame] | 138 | * Returns true if message should be dropped by caller, i.e., if it is a |
| 139 | * trial message or we are inside trial period. Otherwise false. |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 140 | */ |
kbuild test robot | da18ab3 | 2018-03-24 03:47:42 +0800 | [diff] [blame] | 141 | static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d, |
| 142 | struct tipc_media_addr *maddr, |
| 143 | struct tipc_bearer *b, |
| 144 | u32 dst, u32 src, |
| 145 | u32 sugg_addr, |
| 146 | u8 *peer_id, |
| 147 | int mtyp) |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 148 | { |
| 149 | struct net *net = d->net; |
| 150 | struct tipc_net *tn = tipc_net(net); |
| 151 | bool trial = time_before(jiffies, tn->addr_trial_end); |
| 152 | u32 self = tipc_own_addr(net); |
| 153 | |
| 154 | if (mtyp == DSC_TRIAL_FAIL_MSG) { |
| 155 | if (!trial) |
| 156 | return true; |
| 157 | |
| 158 | /* Ignore if somebody else already gave new suggestion */ |
| 159 | if (dst != tn->trial_addr) |
| 160 | return true; |
| 161 | |
| 162 | /* Otherwise update trial address and restart trial period */ |
| 163 | tn->trial_addr = sugg_addr; |
| 164 | msg_set_prevnode(buf_msg(d->skb), sugg_addr); |
| 165 | tn->addr_trial_end = jiffies + msecs_to_jiffies(1000); |
| 166 | return true; |
| 167 | } |
| 168 | |
| 169 | /* Apply trial address if we just left trial period */ |
| 170 | if (!trial && !self) { |
Xin Long | be07f05 | 2021-05-18 10:09:08 +0800 | [diff] [blame] | 171 | schedule_work(&tn->work); |
Jon Maloy | adba75b | 2018-11-16 16:55:04 -0500 | [diff] [blame] | 172 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 173 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); |
| 174 | } |
| 175 | |
Jon Maloy | e415577 | 2018-07-06 20:10:04 +0200 | [diff] [blame] | 176 | /* Accept regular link requests/responses only after trial period */ |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 177 | if (mtyp != DSC_TRIAL_MSG) |
Jon Maloy | e415577 | 2018-07-06 20:10:04 +0200 | [diff] [blame] | 178 | return trial; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 179 | |
| 180 | sugg_addr = tipc_node_try_addr(net, peer_id, src); |
| 181 | if (sugg_addr) |
| 182 | tipc_disc_msg_xmit(net, DSC_TRIAL_FAIL_MSG, src, |
| 183 | self, sugg_addr, maddr, b); |
| 184 | return true; |
| 185 | } |
| 186 | |
Allan Stephens | e91ed0b | 2006-10-16 21:44:59 -0700 | [diff] [blame] | 187 | /** |
Jon Paul Maloy | c82910e | 2014-05-14 05:39:14 -0400 | [diff] [blame] | 188 | * tipc_disc_rcv - handle incoming discovery message (request or response) |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 189 | * @net: applicable net namespace |
| 190 | * @skb: buffer containing message |
| 191 | * @b: bearer that message arrived on |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 192 | */ |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 193 | void tipc_disc_rcv(struct net *net, struct sk_buff *skb, |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 194 | struct tipc_bearer *b) |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 195 | { |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 196 | struct tipc_net *tn = tipc_net(net); |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 197 | struct tipc_msg *hdr = buf_msg(skb); |
Tuong Lien | 31e4ccc | 2019-12-10 15:21:05 +0700 | [diff] [blame] | 198 | u32 pnet_hash = msg_peer_net_hash(hdr); |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 199 | u16 caps = msg_node_capabilities(hdr); |
Jon Maloy | b89afb1 | 2018-03-22 20:42:48 +0100 | [diff] [blame] | 200 | bool legacy = tn->legacy_addr_format; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 201 | u32 sugg = msg_sugg_node_addr(hdr); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 202 | u32 signature = msg_node_sig(hdr); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 203 | u8 peer_id[NODE_ID_LEN] = {0,}; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 204 | u32 dst = msg_dest_domain(hdr); |
| 205 | u32 net_id = msg_bc_netid(hdr); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 206 | struct tipc_media_addr maddr; |
| 207 | u32 src = msg_prevnode(hdr); |
| 208 | u32 mtyp = msg_type(hdr); |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 209 | bool dupl_addr = false; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 210 | bool respond = false; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 211 | u32 self; |
Richard Alpe | e994292 | 2016-06-27 13:34:06 +0200 | [diff] [blame] | 212 | int err; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 213 | |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 214 | skb_linearize(skb); |
| 215 | hdr = buf_msg(skb); |
| 216 | |
| 217 | if (caps & TIPC_NODE_ID128) |
| 218 | memcpy(peer_id, msg_node_id(hdr), NODE_ID_LEN); |
| 219 | else |
| 220 | sprintf(peer_id, "%x", src); |
| 221 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 222 | err = b->media->msg2addr(b, &maddr, msg_media_addr(hdr)); |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 223 | kfree_skb(skb); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 224 | if (err || maddr.broadcast) { |
| 225 | pr_warn_ratelimited("Rcv corrupt discovery message\n"); |
Richard Alpe | e994292 | 2016-06-27 13:34:06 +0200 | [diff] [blame] | 226 | return; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 227 | } |
| 228 | /* Ignore discovery messages from own node */ |
| 229 | if (!memcmp(&maddr, &b->addr, sizeof(maddr))) |
| 230 | return; |
Ying Xue | c93d3ba | 2015-01-09 15:27:04 +0800 | [diff] [blame] | 231 | if (net_id != tn->net_id) |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 232 | return; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 233 | if (tipc_disc_addr_trial_msg(b->disc, &maddr, b, dst, |
| 234 | src, sugg, peer_id, mtyp)) |
| 235 | return; |
| 236 | self = tipc_own_addr(net); |
| 237 | |
| 238 | /* Message from somebody using this node's address */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 239 | if (in_own_node(net, src)) { |
| 240 | disc_dupl_alert(b, self, &maddr); |
Jon Paul Maloy | c82910e | 2014-05-14 05:39:14 -0400 | [diff] [blame] | 241 | return; |
Allan Stephens | a728750 | 2011-02-28 10:03:05 -0500 | [diff] [blame] | 242 | } |
Jon Maloy | b89afb1 | 2018-03-22 20:42:48 +0100 | [diff] [blame] | 243 | if (!tipc_in_scope(legacy, dst, self)) |
| 244 | return; |
| 245 | if (!tipc_in_scope(legacy, b->domain, src)) |
| 246 | return; |
Tuong Lien | 31e4ccc | 2019-12-10 15:21:05 +0700 | [diff] [blame] | 247 | tipc_node_check_dest(net, src, peer_id, b, caps, signature, pnet_hash, |
| 248 | &maddr, &respond, &dupl_addr); |
Jon Paul Maloy | cf14881 | 2015-07-30 18:24:22 -0400 | [diff] [blame] | 249 | if (dupl_addr) |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 250 | disc_dupl_alert(b, src, &maddr); |
| 251 | if (!respond) |
| 252 | return; |
| 253 | if (mtyp != DSC_REQ_MSG) |
| 254 | return; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 255 | tipc_disc_msg_xmit(net, DSC_RESP_MSG, src, self, 0, &maddr, b); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 256 | } |
Allan Stephens | 97878a4 | 2011-10-28 17:30:08 -0400 | [diff] [blame] | 257 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 258 | /* tipc_disc_add_dest - increment set of discovered nodes |
| 259 | */ |
| 260 | void tipc_disc_add_dest(struct tipc_discoverer *d) |
| 261 | { |
| 262 | spin_lock_bh(&d->lock); |
| 263 | d->num_nodes++; |
| 264 | spin_unlock_bh(&d->lock); |
| 265 | } |
| 266 | |
| 267 | /* tipc_disc_remove_dest - decrement set of discovered nodes |
| 268 | */ |
| 269 | void tipc_disc_remove_dest(struct tipc_discoverer *d) |
| 270 | { |
| 271 | int intv, num; |
| 272 | |
| 273 | spin_lock_bh(&d->lock); |
| 274 | d->num_nodes--; |
| 275 | num = d->num_nodes; |
| 276 | intv = d->timer_intv; |
| 277 | if (!num && (intv == TIPC_DISC_INACTIVE || intv > TIPC_DISC_FAST)) { |
| 278 | d->timer_intv = TIPC_DISC_INIT; |
| 279 | mod_timer(&d->timer, jiffies + d->timer_intv); |
Allan Stephens | a728750 | 2011-02-28 10:03:05 -0500 | [diff] [blame] | 280 | } |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 281 | spin_unlock_bh(&d->lock); |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 282 | } |
| 283 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 284 | /* tipc_disc_timeout - send a periodic link setup request |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 285 | * Called whenever a link setup request timer associated with a bearer expires. |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 286 | * - Keep doubling time between sent request until limit is reached; |
| 287 | * - Hold at fast polling rate if we don't have any associated nodes |
| 288 | * - Otherwise hold at slow polling rate |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 289 | */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 290 | static void tipc_disc_timeout(struct timer_list *t) |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 291 | { |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 292 | struct tipc_discoverer *d = from_timer(d, t, timer); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 293 | struct tipc_net *tn = tipc_net(d->net); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 294 | struct tipc_media_addr maddr; |
| 295 | struct sk_buff *skb = NULL; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 296 | struct net *net = d->net; |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 297 | u32 bearer_id; |
Allan Stephens | 972a77f | 2011-04-21 20:34:03 -0500 | [diff] [blame] | 298 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 299 | spin_lock_bh(&d->lock); |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 300 | |
Allan Stephens | 972a77f | 2011-04-21 20:34:03 -0500 | [diff] [blame] | 301 | /* Stop searching if only desired node has been found */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 302 | if (tipc_node(d->domain) && d->num_nodes) { |
| 303 | d->timer_intv = TIPC_DISC_INACTIVE; |
Allan Stephens | 972a77f | 2011-04-21 20:34:03 -0500 | [diff] [blame] | 304 | goto exit; |
| 305 | } |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 306 | |
Jon Maloy | adba75b | 2018-11-16 16:55:04 -0500 | [diff] [blame] | 307 | /* Did we just leave trial period ? */ |
| 308 | if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) { |
| 309 | mod_timer(&d->timer, jiffies + TIPC_DISC_INIT); |
| 310 | spin_unlock_bh(&d->lock); |
Xin Long | be07f05 | 2021-05-18 10:09:08 +0800 | [diff] [blame] | 311 | schedule_work(&tn->work); |
Jon Maloy | adba75b | 2018-11-16 16:55:04 -0500 | [diff] [blame] | 312 | return; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 313 | } |
| 314 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 315 | /* Adjust timeout interval according to discovery phase */ |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 316 | if (time_before(jiffies, tn->addr_trial_end)) { |
| 317 | d->timer_intv = TIPC_DISC_INIT; |
| 318 | } else { |
| 319 | d->timer_intv *= 2; |
| 320 | if (d->num_nodes && d->timer_intv > TIPC_DISC_SLOW) |
| 321 | d->timer_intv = TIPC_DISC_SLOW; |
| 322 | else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST) |
| 323 | d->timer_intv = TIPC_DISC_FAST; |
Jon Maloy | adba75b | 2018-11-16 16:55:04 -0500 | [diff] [blame] | 324 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); |
| 325 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 326 | } |
| 327 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 328 | mod_timer(&d->timer, jiffies + d->timer_intv); |
| 329 | memcpy(&maddr, &d->dest, sizeof(maddr)); |
| 330 | skb = skb_clone(d->skb, GFP_ATOMIC); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 331 | bearer_id = d->bearer_id; |
Allan Stephens | 972a77f | 2011-04-21 20:34:03 -0500 | [diff] [blame] | 332 | exit: |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 333 | spin_unlock_bh(&d->lock); |
| 334 | if (skb) |
| 335 | tipc_bearer_xmit_skb(net, bearer_id, skb, &maddr); |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | /** |
Allan Stephens | 3a777ff | 2011-04-21 13:58:26 -0500 | [diff] [blame] | 339 | * tipc_disc_create - create object to send periodic link setup requests |
Ying Xue | c93d3ba | 2015-01-09 15:27:04 +0800 | [diff] [blame] | 340 | * @net: the applicable net namespace |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 341 | * @b: ptr to bearer issuing requests |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 342 | * @dest: destination address for request messages |
Andrew Lunn | d814120 | 2020-07-13 01:15:14 +0200 | [diff] [blame] | 343 | * @skb: pointer to created frame |
YOSHIFUJI Hideaki | c430728 | 2007-02-09 23:25:21 +0900 | [diff] [blame] | 344 | * |
Randy Dunlap | 637b77f | 2020-11-29 10:32:48 -0800 | [diff] [blame] | 345 | * Return: 0 if successful, otherwise -errno. |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 346 | */ |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 347 | int tipc_disc_create(struct net *net, struct tipc_bearer *b, |
Jon Paul Maloy | 4e801fa | 2016-04-07 10:09:13 -0400 | [diff] [blame] | 348 | struct tipc_media_addr *dest, struct sk_buff **skb) |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 349 | { |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 350 | struct tipc_net *tn = tipc_net(net); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 351 | struct tipc_discoverer *d; |
Per Liden | b97bf3f | 2006-01-02 19:04:38 +0100 | [diff] [blame] | 352 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 353 | d = kmalloc(sizeof(*d), GFP_ATOMIC); |
| 354 | if (!d) |
Allan Stephens | 3a777ff | 2011-04-21 13:58:26 -0500 | [diff] [blame] | 355 | return -ENOMEM; |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 356 | d->skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC); |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 357 | if (!d->skb) { |
| 358 | kfree(d); |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 359 | return -ENOMEM; |
Ying Xue | 22e7987 | 2014-04-25 10:44:15 +0800 | [diff] [blame] | 360 | } |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 361 | tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b); |
Jon Maloy | 25b0b9c | 2018-03-22 20:42:51 +0100 | [diff] [blame] | 362 | |
| 363 | /* Do we need an address trial period first ? */ |
| 364 | if (!tipc_own_addr(net)) { |
| 365 | tn->addr_trial_end = jiffies + msecs_to_jiffies(1000); |
| 366 | msg_set_type(buf_msg(d->skb), DSC_TRIAL_MSG); |
| 367 | } |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 368 | memcpy(&d->dest, dest, sizeof(*dest)); |
| 369 | d->net = net; |
| 370 | d->bearer_id = b->identity; |
| 371 | d->domain = b->domain; |
| 372 | d->num_nodes = 0; |
| 373 | d->timer_intv = TIPC_DISC_INIT; |
| 374 | spin_lock_init(&d->lock); |
| 375 | timer_setup(&d->timer, tipc_disc_timeout, 0); |
| 376 | mod_timer(&d->timer, jiffies + d->timer_intv); |
| 377 | b->disc = d; |
| 378 | *skb = skb_clone(d->skb, GFP_ATOMIC); |
Allan Stephens | 3a777ff | 2011-04-21 13:58:26 -0500 | [diff] [blame] | 379 | return 0; |
| 380 | } |
| 381 | |
| 382 | /** |
| 383 | * tipc_disc_delete - destroy object sending periodic link setup requests |
Randy Dunlap | 5fcb7d4 | 2020-11-29 10:32:50 -0800 | [diff] [blame] | 384 | * @d: ptr to link dest structure |
Allan Stephens | 3a777ff | 2011-04-21 13:58:26 -0500 | [diff] [blame] | 385 | */ |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 386 | void tipc_disc_delete(struct tipc_discoverer *d) |
Allan Stephens | 3a777ff | 2011-04-21 13:58:26 -0500 | [diff] [blame] | 387 | { |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 388 | del_timer_sync(&d->timer); |
| 389 | kfree_skb(d->skb); |
| 390 | kfree(d); |
YOSHIFUJI Hideaki | c430728 | 2007-02-09 23:25:21 +0900 | [diff] [blame] | 391 | } |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 392 | |
| 393 | /** |
| 394 | * tipc_disc_reset - reset object to send periodic link setup requests |
Ying Xue | c93d3ba | 2015-01-09 15:27:04 +0800 | [diff] [blame] | 395 | * @net: the applicable net namespace |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 396 | * @b: ptr to bearer issuing requests |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 397 | */ |
Jon Paul Maloy | 1a90632 | 2015-11-19 14:30:47 -0500 | [diff] [blame] | 398 | void tipc_disc_reset(struct net *net, struct tipc_bearer *b) |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 399 | { |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 400 | struct tipc_discoverer *d = b->disc; |
| 401 | struct tipc_media_addr maddr; |
Jon Paul Maloy | 60852d6 | 2015-10-22 08:51:44 -0400 | [diff] [blame] | 402 | struct sk_buff *skb; |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 403 | |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 404 | spin_lock_bh(&d->lock); |
| 405 | tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b); |
| 406 | d->net = net; |
| 407 | d->bearer_id = b->identity; |
| 408 | d->domain = b->domain; |
| 409 | d->num_nodes = 0; |
| 410 | d->timer_intv = TIPC_DISC_INIT; |
| 411 | memcpy(&maddr, &d->dest, sizeof(maddr)); |
| 412 | mod_timer(&d->timer, jiffies + d->timer_intv); |
| 413 | skb = skb_clone(d->skb, GFP_ATOMIC); |
| 414 | spin_unlock_bh(&d->lock); |
Jon Paul Maloy | 60852d6 | 2015-10-22 08:51:44 -0400 | [diff] [blame] | 415 | if (skb) |
Jon Maloy | b39e465 | 2018-03-22 20:42:46 +0100 | [diff] [blame] | 416 | tipc_bearer_xmit_skb(net, b->identity, skb, &maddr); |
Ying Xue | a8b9b96e | 2014-04-21 10:55:52 +0800 | [diff] [blame] | 417 | } |