aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/discover.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/discover.c')
-rw-r--r--net/tipc/discover.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index ee94de92ae99..3b0cd12f37da 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -132,6 +132,28 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
132} 132}
133 133
134/** 134/**
135 * disc_dupl_alert - issue node address duplication alert
136 * @b_ptr: pointer to bearer detecting duplication
137 * @node_addr: duplicated node address
138 * @media_addr: media address advertised by duplicated node
139 */
140
141static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
142 struct tipc_media_addr *media_addr)
143{
144 char node_addr_str[16];
145 char media_addr_str[64];
146 struct print_buf pb;
147
148 addr_string_fill(node_addr_str, node_addr);
149 tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
150 tipc_media_addr_printf(&pb, media_addr);
151 tipc_printbuf_validate(&pb);
152 warn("Duplicate %s using %s seen on <%s>\n",
153 node_addr_str, media_addr_str, b_ptr->publ.name);
154}
155
156/**
135 * tipc_disc_recv_msg - handle incoming link setup message (request or response) 157 * tipc_disc_recv_msg - handle incoming link setup message (request or response)
136 * @buf: buffer containing message 158 * @buf: buffer containing message
137 */ 159 */
@@ -157,8 +179,11 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
157 return; 179 return;
158 if (!tipc_addr_node_valid(orig)) 180 if (!tipc_addr_node_valid(orig))
159 return; 181 return;
160 if (orig == tipc_own_addr) 182 if (orig == tipc_own_addr) {
183 if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr)))
184 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
161 return; 185 return;
186 }
162 if (!in_scope(dest, tipc_own_addr)) 187 if (!in_scope(dest, tipc_own_addr))
163 return; 188 return;
164 if (is_slave(tipc_own_addr) && is_slave(orig)) 189 if (is_slave(tipc_own_addr) && is_slave(orig))
@@ -170,7 +195,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
170 struct sk_buff *rbuf; 195 struct sk_buff *rbuf;
171 struct tipc_media_addr *addr; 196 struct tipc_media_addr *addr;
172 struct node *n_ptr = tipc_node_find(orig); 197 struct node *n_ptr = tipc_node_find(orig);
173 int link_up; 198 int link_fully_up;
199
174 dbg(" in own cluster\n"); 200 dbg(" in own cluster\n");
175 if (n_ptr == NULL) { 201 if (n_ptr == NULL) {
176 n_ptr = tipc_node_create(orig); 202 n_ptr = tipc_node_create(orig);
@@ -190,14 +216,19 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
190 } 216 }
191 addr = &link->media_addr; 217 addr = &link->media_addr;
192 if (memcmp(addr, &media_addr, sizeof(*addr))) { 218 if (memcmp(addr, &media_addr, sizeof(*addr))) {
219 if (tipc_link_is_up(link) || (!link->started)) {
220 disc_dupl_alert(b_ptr, orig, &media_addr);
221 spin_unlock_bh(&n_ptr->lock);
222 return;
223 }
193 warn("Resetting link <%s>, peer interface address changed\n", 224 warn("Resetting link <%s>, peer interface address changed\n",
194 link->name); 225 link->name);
195 memcpy(addr, &media_addr, sizeof(*addr)); 226 memcpy(addr, &media_addr, sizeof(*addr));
196 tipc_link_reset(link); 227 tipc_link_reset(link);
197 } 228 }
198 link_up = tipc_link_is_up(link); 229 link_fully_up = (link->state == WORKING_WORKING);
199 spin_unlock_bh(&n_ptr->lock); 230 spin_unlock_bh(&n_ptr->lock);
200 if ((type == DSC_RESP_MSG) || link_up) 231 if ((type == DSC_RESP_MSG) || link_fully_up)
201 return; 232 return;
202 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 233 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
203 if (rbuf != NULL) { 234 if (rbuf != NULL) {