/*
* net/tipc/discover.c
- *
- * Copyright (c) 2003-2005, Ericsson Research Canada
- * Copyright (c) 2005, Wind River Systems
- * Copyright (c) 2005-2006, Ericsson AB
+ *
+ * Copyright (c) 2003-2006, Ericsson AB
+ * Copyright (c) 2005-2006, Wind River Systems
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define CHECK_LINK_COUNT 306
#endif
-/*
+/*
* TODO: Most of the inter-cluster setup stuff should be
* rewritten, and be made conformant with specification.
- */
+ */
/**
#if 0
-int disc_create_link(const struct tipc_link_create *argv)
+int disc_create_link(const struct tipc_link_create *argv)
{
- /*
- * Code for inter cluster link setup here
+ /*
+ * Code for inter cluster link setup here
*/
return TIPC_OK;
}
* disc_lost_link(): A link has lost contact
*/
-void disc_link_event(u32 addr, char *name, int up)
+void tipc_disc_link_event(u32 addr, char *name, int up)
{
if (in_own_cluster(addr))
return;
- /*
- * Code for inter cluster link setup here
+ /*
+ * Code for inter cluster link setup here
*/
}
-/**
- * disc_init_msg - initialize a link setup message
+/**
+ * tipc_disc_init_msg - initialize a link setup message
* @type: message type (request or response)
* @req_links: number of links associated with message
* @dest_domain: network domain of node(s) which should respond to message
* @b_ptr: ptr to bearer issuing message
*/
-struct sk_buff *disc_init_msg(u32 type,
- u32 req_links,
- u32 dest_domain,
- struct bearer *b_ptr)
+static struct sk_buff *tipc_disc_init_msg(u32 type,
+ u32 req_links,
+ u32 dest_domain,
+ struct bearer *b_ptr)
{
struct sk_buff *buf = buf_acquire(DSC_H_SIZE);
struct tipc_msg *msg;
if (buf) {
msg = buf_msg(buf);
- msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE,
- dest_domain);
- msg_set_non_seq(msg);
+ msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain);
+ msg_set_non_seq(msg, 1);
msg_set_req_links(msg, req_links);
msg_set_dest_domain(msg, dest_domain);
msg_set_bc_netid(msg, tipc_net_id);
}
/**
- * disc_recv_msg - handle incoming link setup message (request or response)
+ * disc_dupl_alert - issue node address duplication alert
+ * @b_ptr: pointer to bearer detecting duplication
+ * @node_addr: duplicated node address
+ * @media_addr: media address advertised by duplicated node
+ */
+
+static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
+ struct tipc_media_addr *media_addr)
+{
+ char node_addr_str[16];
+ char media_addr_str[64];
+ struct print_buf pb;
+
+ addr_string_fill(node_addr_str, node_addr);
+ tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
+ tipc_media_addr_printf(&pb, media_addr);
+ tipc_printbuf_validate(&pb);
+ warn("Duplicate %s using %s seen on <%s>\n",
+ node_addr_str, media_addr_str, b_ptr->publ.name);
+}
+
+/**
+ * tipc_disc_recv_msg - handle incoming link setup message (request or response)
* @buf: buffer containing message
+ * @b_ptr: bearer that message arrived on
*/
-void disc_recv_msg(struct sk_buff *buf)
+void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
{
- struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle;
struct link *link;
struct tipc_media_addr media_addr;
struct tipc_msg *msg = buf_msg(buf);
if (net_id != tipc_net_id)
return;
- if (!addr_domain_valid(dest))
+ if (!tipc_addr_domain_valid(dest))
return;
- if (!addr_node_valid(orig))
+ if (!tipc_addr_node_valid(orig))
return;
- if (orig == tipc_own_addr)
+ if (orig == tipc_own_addr) {
+ if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr)))
+ disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
return;
+ }
if (!in_scope(dest, tipc_own_addr))
return;
if (is_slave(tipc_own_addr) && is_slave(orig))
/* Always accept link here */
struct sk_buff *rbuf;
struct tipc_media_addr *addr;
- struct node *n_ptr = node_find(orig);
- int link_up;
+ struct tipc_node *n_ptr = tipc_node_find(orig);
+ int link_fully_up;
+
dbg(" in own cluster\n");
if (n_ptr == NULL) {
- n_ptr = node_create(orig);
- }
- if (n_ptr == NULL) {
- warn("Memory squeeze; Failed to create node\n");
- return;
+ n_ptr = tipc_node_create(orig);
+ if (!n_ptr)
+ return;
}
spin_lock_bh(&n_ptr->lock);
link = n_ptr->links[b_ptr->identity];
if (!link) {
dbg("creating link\n");
- link = link_create(b_ptr, orig, &media_addr);
+ link = tipc_link_create(b_ptr, orig, &media_addr);
if (!link) {
- spin_unlock_bh(&n_ptr->lock);
+ spin_unlock_bh(&n_ptr->lock);
return;
}
}
addr = &link->media_addr;
if (memcmp(addr, &media_addr, sizeof(*addr))) {
- char addr_string[16];
-
- warn("New bearer address for %s\n",
- addr_string_fill(addr_string, orig));
+ if (tipc_link_is_up(link) || (!link->started)) {
+ disc_dupl_alert(b_ptr, orig, &media_addr);
+ spin_unlock_bh(&n_ptr->lock);
+ return;
+ }
+ warn("Resetting link <%s>, peer interface address changed\n",
+ link->name);
memcpy(addr, &media_addr, sizeof(*addr));
- link_reset(link);
+ tipc_link_reset(link);
}
- link_up = link_is_up(link);
- spin_unlock_bh(&n_ptr->lock);
- if ((type == DSC_RESP_MSG) || link_up)
+ link_fully_up = (link->state == WORKING_WORKING);
+ spin_unlock_bh(&n_ptr->lock);
+ if ((type == DSC_RESP_MSG) || link_fully_up)
return;
- rbuf = disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
+ rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
if (rbuf != NULL) {
msg_dbg(buf_msg(rbuf),"SEND:");
b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr);
}
/**
- * disc_stop_link_req - stop sending periodic link setup requests
+ * tipc_disc_stop_link_req - stop sending periodic link setup requests
* @req: ptr to link request structure
*/
-void disc_stop_link_req(struct link_req *req)
+void tipc_disc_stop_link_req(struct link_req *req)
{
if (!req)
return;
-
+
k_cancel_timer(&req->timer);
k_term_timer(&req->timer);
buf_discard(req->buf);
kfree(req);
-}
+}
/**
- * disc_update_link_req - update frequency of periodic link setup requests
+ * tipc_disc_update_link_req - update frequency of periodic link setup requests
* @req: ptr to link request structure
*/
-void disc_update_link_req(struct link_req *req)
+void tipc_disc_update_link_req(struct link_req *req)
{
if (!req)
return;
} else {
/* leave timer "as is" if haven't yet reached a "normal" rate */
}
-}
+}
/**
* disc_timeout - send a periodic link setup request
* @req: ptr to link request structure
- *
+ *
* Called whenever a link setup request timer associated with a bearer expires.
*/
-static void disc_timeout(struct link_req *req)
+static void disc_timeout(struct link_req *req)
{
- struct tipc_msg *msg = buf_msg(req->buf);
-
spin_lock_bh(&req->bearer->publ.lock);
-#if 0
- /* CURRENTLY DON'T SUPPORT INTER-ZONE LINKS */
- u32 dest_domain = msg_dest_domain(msg);
- int stop = 0;
- if (!in_scope(dest_domain, tipc_own_addr)) {
- struct _zone *z_ptr = zone_find(dest_domain);
-
- if (z_ptr && (z_ptr->links >= msg_req_links(msg)))
- stop = 1;
- if (req->timer_intv >= 32000)
- stop = 1;
- }
- if (stop) {
- k_cancel_timer(&req->timer);
- buf_discard(req->buf);
- kfree(req);
- spin_unlock_bh(&req->bearer->publ.lock);
- return;
- }
-#endif
-
- msg_dbg(msg,"SEND:");
req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest);
if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
req->timer_intv *= 2;
if (req->timer_intv > TIPC_LINK_REQ_FAST)
req->timer_intv = TIPC_LINK_REQ_FAST;
- if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
+ if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
(req->bearer->nodes.count))
req->timer_intv = TIPC_LINK_REQ_SLOW;
}
}
/**
- * disc_init_link_req - start sending periodic link setup requests
+ * tipc_disc_init_link_req - start sending periodic link setup requests
* @b_ptr: ptr to bearer issuing requests
* @dest: destination address for request messages
* @dest_domain: network domain of node(s) which should respond to message
* @req_links: max number of desired links
- *
+ *
* Returns pointer to link request structure, or NULL if unable to create.
*/
-struct link_req *disc_init_link_req(struct bearer *b_ptr,
- const struct tipc_media_addr *dest,
- u32 dest_domain,
- u32 req_links)
+struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
+ const struct tipc_media_addr *dest,
+ u32 dest_domain,
+ u32 req_links)
{
struct link_req *req;
- req = (struct link_req *)kmalloc(sizeof(*req), GFP_ATOMIC);
+ req = kmalloc(sizeof(*req), GFP_ATOMIC);
if (!req)
return NULL;
- req->buf = disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr);
+ req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr);
if (!req->buf) {
kfree(req);
return NULL;
k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
k_start_timer(&req->timer, req->timer_intv);
return req;
-}
+}