···39394040#include "bcast.h"41414242-#define MAX_BEARERS 84343-#define MAX_MEDIA 44242+#define MAX_BEARERS 24343+#define MAX_MEDIA 244444545/*4646 * Identifiers of supported TIPC media types
-1
net/tipc/config.h
···6565 const void *req_tlv_area, int req_tlv_space,6666 int headroom);67676868-void tipc_cfg_link_event(u32 addr, char *name, int up);6968int tipc_cfg_init(void);7069void tipc_cfg_stop(void);7170
-6
net/tipc/discover.c
···159159 }160160 tipc_node_lock(n_ptr);161161162162- /* Don't talk to neighbor during cleanup after last session */163163- if (n_ptr->cleanup_required) {164164- tipc_node_unlock(n_ptr);165165- return;166166- }167167-168162 link = n_ptr->links[b_ptr->identity];169163170164 /* Create a link endpoint for this bearer, if necessary */
+13-17
net/tipc/eth_media.c
···22 * net/tipc/eth_media.c: Ethernet bearer support for TIPC33 *44 * Copyright (c) 2001-2007, Ericsson AB55- * Copyright (c) 2005-2007, Wind River Systems55+ * Copyright (c) 2005-2008, 2011, Wind River Systems66 * All rights reserved.77 *88 * Redistribution and use in source and binary forms, with or without···3737#include "core.h"3838#include "bearer.h"39394040-#define MAX_ETH_BEARERS 24040+#define MAX_ETH_BEARERS MAX_BEARERS4141#define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI4242#define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL4343#define ETH_LINK_WINDOW TIPC_DEF_LINK_WIN···144144145145 /* Find device with specified name */146146147147+ read_lock(&dev_base_lock);147148 for_each_netdev(&init_net, pdev) {148149 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {149150 dev = pdev;151151+ dev_hold(dev);150152 break;151153 }152154 }155155+ read_unlock(&dev_base_lock);153156 if (!dev)154157 return -ENODEV;155158156156- /* Find Ethernet bearer for device (or create one) */159159+ /* Create Ethernet bearer for device */157160158158- while ((eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev))159159- eb_ptr++;160160- if (eb_ptr == stop)161161- return -EDQUOT;162162- if (!eb_ptr->dev) {163163- eb_ptr->dev = dev;164164- eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC);165165- eb_ptr->tipc_packet_type.dev = dev;166166- eb_ptr->tipc_packet_type.func = recv_msg;167167- eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;168168- INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));169169- dev_hold(dev);170170- dev_add_pack(&eb_ptr->tipc_packet_type);171171- }161161+ eb_ptr->dev = dev;162162+ eb_ptr->tipc_packet_type.type = htons(ETH_P_TIPC);163163+ eb_ptr->tipc_packet_type.dev = dev;164164+ eb_ptr->tipc_packet_type.func = recv_msg;165165+ eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;166166+ INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));167167+ dev_add_pack(&eb_ptr->tipc_packet_type);172168173169 /* Associate TIPC bearer with Ethernet bearer */174170
+82-33
net/tipc/link.c
···332332333333 l_ptr->addr = peer;334334 if_name = strchr(b_ptr->name, ':') + 1;335335- sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",335335+ sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",336336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),337337 tipc_node(tipc_own_addr),338338 if_name,339339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));340340- /* note: peer i/f is appended to link name by reset/activate */340340+ /* note: peer i/f name is updated by reset/activate message */341341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));342342 l_ptr->owner = n_ptr;343343 l_ptr->checkpoint = 1;344344+ l_ptr->peer_session = INVALID_SESSION;344345 l_ptr->b_ptr = b_ptr;345346 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);346347 l_ptr->state = RESET_UNKNOWN;···537536 l_ptr->proto_msg_queue = NULL;538537}539538540540-/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */541541-#define link_send_event(fcn, l_ptr, up) do { } while (0)542542-543539void tipc_link_reset(struct link *l_ptr)544540{545541 struct sk_buff *buf;···594596 l_ptr->fsm_msg_cnt = 0;595597 l_ptr->stale_count = 0;596598 link_reset_statistics(l_ptr);597597-598598- link_send_event(tipc_cfg_link_event, l_ptr, 0);599599- if (!in_own_cluster(l_ptr->addr))600600- link_send_event(tipc_disc_link_event, l_ptr, 0);601599}602600603601···602608 l_ptr->next_in_no = l_ptr->stats.recv_info = 1;603609 tipc_node_link_up(l_ptr->owner, l_ptr);604610 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);605605- link_send_event(tipc_cfg_link_event, l_ptr, 1);606606- if (!in_own_cluster(l_ptr->addr))607607- link_send_event(tipc_disc_link_event, l_ptr, 1);608611}609612610613/**···976985}977986978987/*988988+ * tipc_link_send_names - send name table entries to new neighbor989989+ *990990+ * Send routine for bulk delivery of name table messages when contact991991+ * with a new neighbor occurs. No link congestion checking is performed992992+ * because name table messages *must* be delivered. The messages must be993993+ * small enough not to require fragmentation.994994+ * Called without any locks held.995995+ */996996+997997+void tipc_link_send_names(struct list_head *message_list, u32 dest)998998+{999999+ struct tipc_node *n_ptr;10001000+ struct link *l_ptr;10011001+ struct sk_buff *buf;10021002+ struct sk_buff *temp_buf;10031003+10041004+ if (list_empty(message_list))10051005+ return;10061006+10071007+ read_lock_bh(&tipc_net_lock);10081008+ n_ptr = tipc_node_find(dest);10091009+ if (n_ptr) {10101010+ tipc_node_lock(n_ptr);10111011+ l_ptr = n_ptr->active_links[0];10121012+ if (l_ptr) {10131013+ /* convert circular list to linear list */10141014+ ((struct sk_buff *)message_list->prev)->next = NULL;10151015+ link_add_chain_to_outqueue(l_ptr,10161016+ (struct sk_buff *)message_list->next, 0);10171017+ tipc_link_push_queue(l_ptr);10181018+ INIT_LIST_HEAD(message_list);10191019+ }10201020+ tipc_node_unlock(n_ptr);10211021+ }10221022+ read_unlock_bh(&tipc_net_lock);10231023+10241024+ /* discard the messages if they couldn't be sent */10251025+10261026+ list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {10271027+ list_del((struct list_head *)buf);10281028+ buf_discard(buf);10291029+ }10301030+}10311031+10321032+/*9791033 * link_send_buf_fast: Entry for data messages where the9801034 * destination link is known and the header is complete,9811035 * inclusive total message length. Very time critical.···10661030 int res;10671031 u32 selector = msg_origport(buf_msg(buf)) & 1;10681032 u32 dummy;10691069-10701070- if (destnode == tipc_own_addr)10711071- return tipc_port_recv_msg(buf);1072103310731034 read_lock_bh(&tipc_net_lock);10741035 n_ptr = tipc_node_find(destnode);···16911658 continue;16921659 }1693166016611661+ /* Discard unicast link messages destined for another node */16621662+16941663 if (unlikely(!msg_short(msg) &&16951664 (msg_destnode(msg) != tipc_own_addr)))16961665 goto cont;16971697-16981698- /* Discard non-routeable messages destined for another node */16991699-17001700- if (unlikely(!msg_isdata(msg) &&17011701- (msg_destnode(msg) != tipc_own_addr))) {17021702- if ((msg_user(msg) != CONN_MANAGER) &&17031703- (msg_user(msg) != MSG_FRAGMENTER))17041704- goto cont;17051705- }1706166617071667 /* Locate neighboring node that sent message */17081668···17041678 goto cont;17051679 tipc_node_lock(n_ptr);1706168017071707- /* Don't talk to neighbor during cleanup after last session */17081708-17091709- if (n_ptr->cleanup_required) {17101710- tipc_node_unlock(n_ptr);17111711- goto cont;17121712- }17131713-17141681 /* Locate unicast link endpoint that should handle message */1715168217161683 l_ptr = n_ptr->links[b_ptr->identity];17171684 if (unlikely(!l_ptr)) {16851685+ tipc_node_unlock(n_ptr);16861686+ goto cont;16871687+ }16881688+16891689+ /* Verify that communication with node is currently allowed */16901690+16911691+ if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&16921692+ msg_user(msg) == LINK_PROTOCOL &&16931693+ (msg_type(msg) == RESET_MSG ||16941694+ msg_type(msg) == ACTIVATE_MSG) &&16951695+ !msg_redundant_link(msg))16961696+ n_ptr->block_setup &= ~WAIT_PEER_DOWN;16971697+16981698+ if (n_ptr->block_setup) {17181699 tipc_node_unlock(n_ptr);17191700 goto cont;17201701 }···1956192319571924 if (link_blocked(l_ptr))19581925 return;19261926+19271927+ /* Abort non-RESET send if communication with node is prohibited */19281928+19291929+ if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))19301930+ return;19311931+19591932 msg_set_type(msg, msg_typ);19601933 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);19611934 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in));···20902051 case RESET_MSG:20912052 if (!link_working_unknown(l_ptr) &&20922053 (l_ptr->peer_session != INVALID_SESSION)) {20932093- if (msg_session(msg) == l_ptr->peer_session)20942094- break; /* duplicate: ignore */20542054+ if (less_eq(msg_session(msg), l_ptr->peer_session))20552055+ break; /* duplicate or old reset: ignore */20952056 }20572057+20582058+ if (!msg_redundant_link(msg) && (link_working_working(l_ptr) ||20592059+ link_working_unknown(l_ptr))) {20602060+ /*20612061+ * peer has lost contact -- don't allow peer's links20622062+ * to reactivate before we recognize loss & clean up20632063+ */20642064+ l_ptr->owner->block_setup = WAIT_NODE_DOWN;20652065+ }20662066+20962067 /* fall thru' */20972068 case ACTIVATE_MSG:20982069 /* Update link settings according other endpoint's values */
···173173 * tipc_named_node_up - tell specified node about all publications by this node174174 */175175176176-void tipc_named_node_up(unsigned long node)176176+void tipc_named_node_up(unsigned long nodearg)177177{178178+ struct tipc_node *n_ptr;179179+ struct link *l_ptr;178180 struct publication *publ;179181 struct distr_item *item = NULL;180182 struct sk_buff *buf = NULL;183183+ struct list_head message_list;184184+ u32 node = (u32)nodearg;181185 u32 left = 0;182186 u32 rest;183183- u32 max_item_buf;187187+ u32 max_item_buf = 0;188188+189189+ /* compute maximum amount of publication data to send per message */190190+191191+ read_lock_bh(&tipc_net_lock);192192+ n_ptr = tipc_node_find(node);193193+ if (n_ptr) {194194+ tipc_node_lock(n_ptr);195195+ l_ptr = n_ptr->active_links[0];196196+ if (l_ptr)197197+ max_item_buf = ((l_ptr->max_pkt - INT_H_SIZE) /198198+ ITEM_SIZE) * ITEM_SIZE;199199+ tipc_node_unlock(n_ptr);200200+ }201201+ read_unlock_bh(&tipc_net_lock);202202+ if (!max_item_buf)203203+ return;204204+205205+ /* create list of publication messages, then send them as a unit */206206+207207+ INIT_LIST_HEAD(&message_list);184208185209 read_lock_bh(&tipc_nametbl_lock);186186- max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE;187187- max_item_buf *= ITEM_SIZE;188210 rest = publ_cnt * ITEM_SIZE;189211190212 list_for_each_entry(publ, &publ_root, local_list) {···224202 item++;225203 left -= ITEM_SIZE;226204 if (!left) {227227- msg_set_link_selector(buf_msg(buf), node);228228- tipc_link_send(buf, node, node);205205+ list_add_tail((struct list_head *)buf, &message_list);229206 buf = NULL;230207 }231208 }232209exit:233210 read_unlock_bh(&tipc_nametbl_lock);211211+212212+ tipc_link_send_names(&message_list, (u32)node);234213}235214236215/**
-11
net/tipc/net.c
···141141 return;142142 msg = buf_msg(buf);143143144144- msg_incr_reroute_cnt(msg);145145- if (msg_reroute_cnt(msg) > 6) {146146- if (msg_errcode(msg)) {147147- buf_discard(buf);148148- } else {149149- tipc_reject_msg(buf, msg_destport(msg) ?150150- TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME);151151- }152152- return;153153- }154154-155144 /* Handle message for this node */156145 dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);157146 if (tipc_in_scope(dnode, tipc_own_addr)) {
+30-25
net/tipc/node.c
···112112 break;113113 }114114 list_add_tail(&n_ptr->list, &temp_node->list);115115+ n_ptr->block_setup = WAIT_PEER_DOWN;115116116117 tipc_num_nodes++;117118···313312 }314313}315314316316-static void node_cleanup_finished(unsigned long node_addr)315315+static void node_name_purge_complete(unsigned long node_addr)317316{318317 struct tipc_node *n_ptr;319318···321320 n_ptr = tipc_node_find(node_addr);322321 if (n_ptr) {323322 tipc_node_lock(n_ptr);324324- n_ptr->cleanup_required = 0;323323+ n_ptr->block_setup &= ~WAIT_NAMES_GONE;325324 tipc_node_unlock(n_ptr);326325 }327326 read_unlock_bh(&tipc_net_lock);···332331 char addr_string[16];333332 u32 i;334333335335- /* Clean up broadcast reception remains */336336- n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;337337- while (n_ptr->bclink.deferred_head) {338338- struct sk_buff *buf = n_ptr->bclink.deferred_head;339339- n_ptr->bclink.deferred_head = buf->next;340340- buf_discard(buf);341341- }342342- if (n_ptr->bclink.defragm) {343343- buf_discard(n_ptr->bclink.defragm);344344- n_ptr->bclink.defragm = NULL;345345- }346346-347347- if (n_ptr->bclink.supported) {348348- tipc_bclink_acknowledge(n_ptr,349349- mod(n_ptr->bclink.acked + 10000));350350- tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);351351- if (n_ptr->addr < tipc_own_addr)352352- tipc_own_tag--;353353- }354354-355334 info("Lost contact with %s\n",356335 tipc_addr_string_fill(addr_string, n_ptr->addr));336336+337337+ /* Flush broadcast link info associated with lost node */338338+339339+ if (n_ptr->bclink.supported) {340340+ n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;341341+ while (n_ptr->bclink.deferred_head) {342342+ struct sk_buff *buf = n_ptr->bclink.deferred_head;343343+ n_ptr->bclink.deferred_head = buf->next;344344+ buf_discard(buf);345345+ }346346+347347+ if (n_ptr->bclink.defragm) {348348+ buf_discard(n_ptr->bclink.defragm);349349+ n_ptr->bclink.defragm = NULL;350350+ }351351+352352+ tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);353353+ tipc_bclink_acknowledge(n_ptr,354354+ mod(n_ptr->bclink.acked + 10000));355355+ if (n_ptr->addr < tipc_own_addr)356356+ tipc_own_tag--;357357+358358+ n_ptr->bclink.supported = 0;359359+ }357360358361 /* Abort link changeover */359362 for (i = 0; i < MAX_BEARERS; i++) {···372367 /* Notify subscribers */373368 tipc_nodesub_notify(n_ptr);374369375375- /* Prevent re-contact with node until all cleanup is done */370370+ /* Prevent re-contact with node until cleanup is done */376371377377- n_ptr->cleanup_required = 1;378378- tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);372372+ n_ptr->block_setup = WAIT_PEER_DOWN | WAIT_NAMES_GONE;373373+ tipc_k_signal((Handler)node_name_purge_complete, n_ptr->addr);379374}380375381376struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
+8-2
net/tipc/node.h
···4242#include "net.h"4343#include "bearer.h"44444545+/* Flags used to block (re)establishment of contact with a neighboring node */4646+4747+#define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */4848+#define WAIT_NAMES_GONE 0x0002 /* wait for peer's publications to be purged */4949+#define WAIT_NODE_DOWN 0x0004 /* wait until peer node is declared down */5050+4551/**4652 * struct tipc_node - TIPC node structure4753 * @addr: network address of node···5852 * @active_links: pointers to active links to node5953 * @links: pointers to all links to node6054 * @working_links: number of working links to node (both active and standby)6161- * @cleanup_required: non-zero if cleaning up after a prior loss of contact5555+ * @block_setup: bit mask of conditions preventing link establishment to node6256 * @link_cnt: number of links to node6357 * @permit_changeover: non-zero if node has redundant links to this system6458 * @bclink: broadcast-related info···8377 struct link *links[MAX_BEARERS];8478 int link_cnt;8579 int working_links;8686- int cleanup_required;8080+ int block_setup;8781 int permit_changeover;8882 struct {8983 int supported;
+24-27
net/tipc/socket.c
···4949 struct sock sk;5050 struct tipc_port *p;5151 struct tipc_portid peer_name;5252- long conn_timeout;5252+ unsigned int conn_timeout;5353};54545555#define tipc_sk(sk) ((struct tipc_sock *)(sk))···231231 sock_init_data(sock, sk);232232 sk->sk_backlog_rcv = backlog_rcv;233233 tipc_sk(sk)->p = tp_ptr;234234- tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);234234+ tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT;235235236236 spin_unlock_bh(tp_ptr->lock);237237···525525 struct tipc_port *tport = tipc_sk_port(sk);526526 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;527527 int needs_conn;528528+ long timeout_val;528529 int res = -EINVAL;529530530531 if (unlikely(!dest))···565564 reject_rx_queue(sk);566565 }567566567567+ timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);568568+568569 do {569570 if (dest->addrtype == TIPC_ADDR_NAME) {570571 res = dest_name_check(dest, m);···603600 sock->state = SS_CONNECTING;604601 break;605602 }606606- if (m->msg_flags & MSG_DONTWAIT) {607607- res = -EWOULDBLOCK;603603+ if (timeout_val <= 0L) {604604+ res = timeout_val ? timeout_val : -EWOULDBLOCK;608605 break;609606 }610607 release_sock(sk);611611- res = wait_event_interruptible(*sk_sleep(sk),612612- !tport->congested);608608+ timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),609609+ !tport->congested, timeout_val);613610 lock_sock(sk);614614- if (res)615615- break;616611 } while (1);617612618613exit:···637636 struct sock *sk = sock->sk;638637 struct tipc_port *tport = tipc_sk_port(sk);639638 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;639639+ long timeout_val;640640 int res;641641642642 /* Handle implied connection establishment */···652650 if (iocb)653651 lock_sock(sk);654652653653+ timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);654654+655655 do {656656 if (unlikely(sock->state != SS_CONNECTED)) {657657 if (sock->state == SS_DISCONNECTING)···667663 total_len);668664 if (likely(res != -ELINKCONG))669665 break;670670- if (m->msg_flags & MSG_DONTWAIT) {671671- res = -EWOULDBLOCK;666666+ if (timeout_val <= 0L) {667667+ res = timeout_val ? timeout_val : -EWOULDBLOCK;672668 break;673669 }674670 release_sock(sk);675675- res = wait_event_interruptible(*sk_sleep(sk),676676- (!tport->congested || !tport->connected));671671+ timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),672672+ (!tport->congested || !tport->connected), timeout_val);677673 lock_sock(sk);678678- if (res)679679- break;680674 } while (1);681675682676 if (iocb)···13711369 struct msghdr m = {NULL,};13721370 struct sk_buff *buf;13731371 struct tipc_msg *msg;13741374- long timeout;13721372+ unsigned int timeout;13751373 int res;1376137413771375 lock_sock(sk);···14361434 res = wait_event_interruptible_timeout(*sk_sleep(sk),14371435 (!skb_queue_empty(&sk->sk_receive_queue) ||14381436 (sock->state != SS_CONNECTING)),14391439- timeout ? timeout : MAX_SCHEDULE_TIMEOUT);14371437+ timeout ? (long)msecs_to_jiffies(timeout)14381438+ : MAX_SCHEDULE_TIMEOUT);14401439 lock_sock(sk);1441144014421441 if (res > 0) {···1483148014841481 lock_sock(sk);1485148214861486- if (sock->state == SS_READY)14871487- res = -EOPNOTSUPP;14881488- else if (sock->state != SS_UNCONNECTED)14831483+ if (sock->state != SS_UNCONNECTED)14891484 res = -EINVAL;14901485 else {14911486 sock->state = SS_LISTENING;···1511151015121511 lock_sock(sk);1513151215141514- if (sock->state == SS_READY) {15151515- res = -EOPNOTSUPP;15161516- goto exit;15171517- }15181513 if (sock->state != SS_LISTENING) {15191514 res = -EINVAL;15201515 goto exit;···16931696 res = tipc_set_portunreturnable(tport->ref, value);16941697 break;16951698 case TIPC_CONN_TIMEOUT:16961696- tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value);16991699+ tipc_sk(sk)->conn_timeout = value;16971700 /* no need to set "res", since already 0 at this point */16981701 break;16991702 default:···17491752 res = tipc_portunreturnable(tport->ref, &value);17501753 break;17511754 case TIPC_CONN_TIMEOUT:17521752- value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);17551755+ value = tipc_sk(sk)->conn_timeout;17531756 /* no need to set "res", since already 0 at this point */17541757 break;17551758 case TIPC_NODE_RECVQ_DEPTH:···17871790 .bind = bind,17881791 .connect = connect,17891792 .socketpair = sock_no_socketpair,17901790- .accept = accept,17931793+ .accept = sock_no_accept,17911794 .getname = get_name,17921795 .poll = poll,17931796 .ioctl = sock_no_ioctl,17941794- .listen = listen,17971797+ .listen = sock_no_listen,17951798 .shutdown = shutdown,17961799 .setsockopt = setsockopt,17971800 .getsockopt = getsockopt,