void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) { struct link *link; struct tipc_media_addr media_addr; struct tipc_msg *msg = buf_msg(buf); u32 dest = msg_dest_domain(msg); u32 orig = msg_prevnode(msg); u32 net_id = msg_bc_netid(msg); u32 type = msg_type(msg); msg_get_media_addr(msg, &media_addr); buf_discard(buf); if (net_id != tipc_net_id) return; if (!tipc_addr_domain_valid(dest)) return; if (!tipc_addr_node_valid(orig)) return; 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 (!tipc_in_scope(dest, tipc_own_addr)) return; if (in_own_cluster(orig)) { /* Always accept link here */ struct sk_buff *rbuf; struct tipc_media_addr *addr; struct tipc_node *n_ptr = tipc_node_find(orig); int link_fully_up; if (n_ptr == NULL) { n_ptr = tipc_node_create(orig); if (!n_ptr) return; } spin_lock_bh(&n_ptr->lock); /* Don't talk to neighbor during cleanup after last session */ if (n_ptr->cleanup_required) { spin_unlock_bh(&n_ptr->lock); return; } link = n_ptr->links[b_ptr->identity]; if (!link) { link = tipc_link_create(b_ptr, orig, &media_addr); if (!link) { 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); } link_fully_up = link_working_working(link); 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) { b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); buf_discard(rbuf); } } }
void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) { struct link *link; struct tipc_media_addr media_addr; struct tipc_msg *msg = buf_msg(buf); u32 dest = msg_dest_domain(msg); u32 orig = msg_prevnode(msg); u32 net_id = msg_bc_netid(msg); u32 type = msg_type(msg); msg_get_media_addr(msg,&media_addr); msg_dbg(msg, "RECV:"); buf_discard(buf); if (net_id != tipc_net_id) return; if (!tipc_addr_domain_valid(dest)) return; if (!tipc_addr_node_valid(orig)) return; 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)) return; if (is_slave(orig) && !in_own_cluster(orig)) return; if (in_own_cluster(orig)) { /* Always accept link here */ struct sk_buff *rbuf; struct tipc_media_addr *addr; struct tipc_node *n_ptr = tipc_node_find(orig); int link_fully_up; dbg(" in own cluster\n"); if (n_ptr == NULL) { 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 = tipc_link_create(b_ptr, orig, &media_addr); if (!link) { 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); } 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) { msg_dbg(buf_msg(rbuf),"SEND:"); b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); buf_discard(rbuf); } } }
void tipc_disc_recv_msg(struct sk_buff *buf) { 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); u32 dest = msg_dest_domain(msg); u32 orig = msg_prevnode(msg); u32 net_id = msg_bc_netid(msg); u32 type = msg_type(msg); msg_get_media_addr(msg,&media_addr); msg_dbg(msg, "RECV:"); buf_discard(buf); if (net_id != tipc_net_id) return; if (!tipc_addr_domain_valid(dest)) return; if (!tipc_addr_node_valid(orig)) return; if (orig == tipc_own_addr) return; if (!in_scope(dest, tipc_own_addr)) return; if (is_slave(tipc_own_addr) && is_slave(orig)) return; if (is_slave(orig) && !in_own_cluster(orig)) return; if (in_own_cluster(orig)) { /* Always accept link here */ struct sk_buff *rbuf; struct tipc_media_addr *addr; struct node *n_ptr = tipc_node_find(orig); int link_up; dbg(" in own cluster\n"); if (n_ptr == NULL) { n_ptr = tipc_node_create(orig); } if (n_ptr == NULL) { warn("Memory squeeze; Failed to create node\n"); return; } spin_lock_bh(&n_ptr->lock); link = n_ptr->links[b_ptr->identity]; if (!link) { dbg("creating link\n"); link = tipc_link_create(b_ptr, orig, &media_addr); if (!link) { 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)); memcpy(addr, &media_addr, sizeof(*addr)); tipc_link_reset(link); } link_up = tipc_link_is_up(link); spin_unlock_bh(&n_ptr->lock); if ((type == DSC_RESP_MSG) || link_up) return; 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); buf_discard(rbuf); } } }