X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=net%2Ftipc%2Fdiscover.c;h=5d643e5721eb45ec36d3fb43d2f205e90f1ec5b5;hb=a3da12229f4f9bee2ed66ac34a54a4e8b74bcbcb;hp=2b84412031203c479d6418bc39965eb5ca36c2ce;hpb=d7fa2589bbe7ab53fd5eb20e8c7e388d5aff6f16;p=linux-2.6-omap-h63xx.git diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 2b844120312..5d643e5721e 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -1,6 +1,6 @@ /* * net/tipc/discover.c - * + * * Copyright (c) 2003-2006, Ericsson AB * Copyright (c) 2005-2006, Wind River Systems * All rights reserved. @@ -56,10 +56,10 @@ #define CHECK_LINK_COUNT 306 #endif -/* +/* * TODO: Most of the inter-cluster setup stuff should be * rewritten, and be made conformant with specification. - */ + */ /** @@ -80,10 +80,10 @@ struct link_req { #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; } @@ -93,16 +93,16 @@ int disc_create_link(const struct tipc_link_create *argv) * disc_lost_link(): A link has lost contact */ -void tipc_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 */ } -/** +/** * tipc_disc_init_msg - initialize a link setup message * @type: message type (request or response) * @req_links: number of links associated with message @@ -131,6 +131,28 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, return buf; } +/** + * 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 @@ -157,8 +179,11 @@ void tipc_disc_recv_msg(struct sk_buff *buf) return; 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)) @@ -170,7 +195,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf) struct sk_buff *rbuf; struct tipc_media_addr *addr; struct node *n_ptr = tipc_node_find(orig); - int link_up; + int link_fully_up; + dbg(" in own cluster\n"); if (n_ptr == NULL) { n_ptr = tipc_node_create(orig); @@ -184,20 +210,25 @@ void tipc_disc_recv_msg(struct sk_buff *buf) dbg("creating link\n"); 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))) { + 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)); - tipc_link_reset(link); + tipc_link_reset(link); } - link_up = tipc_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 = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); if (rbuf != NULL) { @@ -213,23 +244,23 @@ void tipc_disc_recv_msg(struct sk_buff *buf) * @req: ptr to link request structure */ -void tipc_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); -} +} /** * tipc_disc_update_link_req - update frequency of periodic link setup requests * @req: ptr to link request structure */ -void tipc_disc_update_link_req(struct link_req *req) +void tipc_disc_update_link_req(struct link_req *req) { if (!req) return; @@ -247,16 +278,16 @@ void tipc_disc_update_link_req(struct link_req *req) } 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) { spin_lock_bh(&req->bearer->publ.lock); @@ -269,7 +300,7 @@ static void disc_timeout(struct link_req *req) 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; } @@ -284,18 +315,18 @@ static void disc_timeout(struct link_req *req) * @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 *tipc_disc_init_link_req(struct bearer *b_ptr, +struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, const struct tipc_media_addr *dest, u32 dest_domain, - u32 req_links) + 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; @@ -311,5 +342,5 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); k_start_timer(&req->timer, req->timer_intv); return req; -} +}