summaryrefslogtreecommitdiff
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c188
1 files changed, 52 insertions, 136 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index a3616b99529..b31992ccd5d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -99,23 +99,6 @@ struct link_name {
char if_peer[TIPC_MAX_IF_NAME];
};
-#if 0
-
-/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
-
-/**
- * struct link_event - link up/down event notification
- */
-
-struct link_event {
- u32 addr;
- int up;
- void (*fcn)(u32, char *, int);
- char name[TIPC_MAX_LINK_NAME];
-};
-
-#endif
-
static void link_handle_out_of_seq_msg(struct link *l_ptr,
struct sk_buff *buf);
static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf);
@@ -129,6 +112,9 @@ static void link_state_event(struct link *l_ptr, u32 event);
static void link_reset_statistics(struct link *l_ptr);
static void link_print(struct link *l_ptr, struct print_buf *buf,
const char *str);
+static void link_start(struct link *l_ptr);
+static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
+
/*
* Debugging code used by link routines only
@@ -239,13 +225,13 @@ int tipc_link_is_up(struct link *l_ptr)
{
if (!l_ptr)
return 0;
- return (link_working_working(l_ptr) || link_working_unknown(l_ptr));
+ return link_working_working(l_ptr) || link_working_unknown(l_ptr);
}
int tipc_link_is_active(struct link *l_ptr)
{
- return ((l_ptr->owner->active_links[0] == l_ptr) ||
- (l_ptr->owner->active_links[1] == l_ptr));
+ return (l_ptr->owner->active_links[0] == l_ptr) ||
+ (l_ptr->owner->active_links[1] == l_ptr);
}
/**
@@ -459,7 +445,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
list_add_tail(&l_ptr->link_list, &b_ptr->links);
- tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr);
+ tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
@@ -499,9 +485,9 @@ void tipc_link_delete(struct link *l_ptr)
kfree(l_ptr);
}
-void tipc_link_start(struct link *l_ptr)
+static void link_start(struct link *l_ptr)
{
- dbg("tipc_link_start %x\n", l_ptr);
+ dbg("link_start %x\n", l_ptr);
link_state_event(l_ptr, STARTING_EVT);
}
@@ -634,39 +620,9 @@ void tipc_link_stop(struct link *l_ptr)
l_ptr->proto_msg_queue = NULL;
}
-#if 0
-
/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
-
-static void link_recv_event(struct link_event *ev)
-{
- ev->fcn(ev->addr, ev->name, ev->up);
- kfree(ev);
-}
-
-static void link_send_event(void (*fcn)(u32 a, char *n, int up),
- struct link *l_ptr, int up)
-{
- struct link_event *ev;
-
- ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
- if (!ev) {
- warn("Link event allocation failure\n");
- return;
- }
- ev->addr = l_ptr->addr;
- ev->up = up;
- ev->fcn = fcn;
- memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME);
- tipc_k_signal((Handler)link_recv_event, (unsigned long)ev);
-}
-
-#else
-
#define link_send_event(fcn, l_ptr, up) do { } while (0)
-#endif
-
void tipc_link_reset(struct link *l_ptr)
{
struct sk_buff *buf;
@@ -690,10 +646,7 @@ void tipc_link_reset(struct link *l_ptr)
tipc_node_link_down(l_ptr->owner, l_ptr);
tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
-#if 0
- tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
- dbg_link_dump();
-#endif
+
if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
l_ptr->owner->permit_changeover) {
l_ptr->reset_checkpoint = checkpoint;
@@ -1050,7 +1003,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
/* Fragmentation needed ? */
if (size > max_packet)
- return tipc_link_send_long_buf(l_ptr, buf);
+ return link_send_long_buf(l_ptr, buf);
/* Packet can be queued or sent: */
@@ -1086,7 +1039,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
/* Try creating a new bundle */
if (size <= max_packet * 2 / 3) {
- struct sk_buff *bundler = buf_acquire(max_packet);
+ struct sk_buff *bundler = tipc_buf_acquire(max_packet);
struct tipc_msg bundler_hdr;
if (bundler) {
@@ -1362,7 +1315,7 @@ again:
/* Prepare header of first fragment: */
- buf_chain = buf = buf_acquire(max_pkt);
+ buf_chain = buf = tipc_buf_acquire(max_pkt);
if (!buf)
return -ENOMEM;
buf->next = NULL;
@@ -1419,7 +1372,7 @@ error:
msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
msg_set_fragm_no(&fragm_hdr, ++fragm_no);
prev = buf;
- buf = buf_acquire(fragm_sz + INT_H_SIZE);
+ buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (!buf)
goto error;
@@ -1802,6 +1755,15 @@ static int link_recv_buf_validate(struct sk_buff *buf)
return pskb_may_pull(buf, hdr_size);
}
+/**
+ * tipc_recv_msg - process TIPC messages arriving from off-node
+ * @head: pointer to message buffer chain
+ * @tb_ptr: pointer to bearer message arrived on
+ *
+ * Invoked with no locks held. Bearer pointer must point to a valid bearer
+ * structure (i.e. cannot be NULL), but bearer can be inactive.
+ */
+
void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
{
read_lock_bh(&tipc_net_lock);
@@ -1819,6 +1781,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
head = head->next;
+ /* Ensure bearer is still enabled */
+
+ if (unlikely(!b_ptr->active))
+ goto cont;
+
/* Ensure message is well-formed */
if (unlikely(!link_recv_buf_validate(buf)))
@@ -1855,13 +1822,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
goto cont;
}
- /* Locate unicast link endpoint that should handle message */
+ /* Locate neighboring node that sent message */
n_ptr = tipc_node_find(msg_prevnode(msg));
if (unlikely(!n_ptr))
goto cont;
tipc_node_lock(n_ptr);
+ /* Don't talk to neighbor during cleanup after last session */
+
+ if (n_ptr->cleanup_required) {
+ tipc_node_unlock(n_ptr);
+ goto cont;
+ }
+
+ /* Locate unicast link endpoint that should handle message */
+
l_ptr = n_ptr->links[b_ptr->identity];
if (unlikely(!l_ptr)) {
tipc_node_unlock(n_ptr);
@@ -2172,7 +2148,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
if (!l_ptr->proto_msg_queue) {
l_ptr->proto_msg_queue =
- buf_acquire(sizeof(l_ptr->proto_msg));
+ tipc_buf_acquire(sizeof(l_ptr->proto_msg));
}
buf = l_ptr->proto_msg_queue;
if (!buf)
@@ -2186,7 +2162,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
msg_dbg(msg, ">>");
- buf = buf_acquire(msg_size);
+ buf = tipc_buf_acquire(msg_size);
if (!buf)
return;
@@ -2345,10 +2321,10 @@ exit:
* tipc_link_tunnel(): Send one message via a link belonging to
* another bearer. Owner node is locked.
*/
-void tipc_link_tunnel(struct link *l_ptr,
- struct tipc_msg *tunnel_hdr,
- struct tipc_msg *msg,
- u32 selector)
+static void tipc_link_tunnel(struct link *l_ptr,
+ struct tipc_msg *tunnel_hdr,
+ struct tipc_msg *msg,
+ u32 selector)
{
struct link *tunnel;
struct sk_buff *buf;
@@ -2361,7 +2337,7 @@ void tipc_link_tunnel(struct link *l_ptr,
return;
}
msg_set_size(tunnel_hdr, length + INT_H_SIZE);
- buf = buf_acquire(length + INT_H_SIZE);
+ buf = tipc_buf_acquire(length + INT_H_SIZE);
if (!buf) {
warn("Link changeover error, "
"unable to send tunnel msg\n");
@@ -2407,7 +2383,7 @@ void tipc_link_changeover(struct link *l_ptr)
if (!l_ptr->first_out) {
struct sk_buff *buf;
- buf = buf_acquire(INT_H_SIZE);
+ buf = tipc_buf_acquire(INT_H_SIZE);
if (buf) {
skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
msg_set_size(&tunnel_hdr, INT_H_SIZE);
@@ -2468,7 +2444,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
- outbuf = buf_acquire(length + INT_H_SIZE);
+ outbuf = tipc_buf_acquire(length + INT_H_SIZE);
if (outbuf == NULL) {
warn("Link changeover error, "
"unable to send duplicate msg\n");
@@ -2504,7 +2480,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
u32 size = msg_size(msg);
struct sk_buff *eb;
- eb = buf_acquire(size);
+ eb = tipc_buf_acquire(size);
if (eb)
skb_copy_to_linear_data(eb, msg, size);
return eb;
@@ -2632,11 +2608,11 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
/*
- * tipc_link_send_long_buf: Entry for buffers needing fragmentation.
+ * link_send_long_buf: Entry for buffers needing fragmentation.
* The buffer is complete, inclusive total message length.
* Returns user data length.
*/
-int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
+static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
{
struct tipc_msg *inmsg = buf_msg(buf);
struct tipc_msg fragm_hdr;
@@ -2675,7 +2651,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
fragm_sz = rest;
msg_set_type(&fragm_hdr, LAST_FRAGMENT);
}
- fragm = buf_acquire(fragm_sz + INT_H_SIZE);
+ fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (fragm == NULL) {
warn("Link unable to fragment message\n");
dsz = -ENOMEM;
@@ -2780,7 +2756,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
buf_discard(fbuf);
return 0;
}
- pbuf = buf_acquire(msg_size(imsg));
+ pbuf = tipc_buf_acquire(msg_size(imsg));
if (pbuf != NULL) {
pbuf->next = *pending;
*pending = pbuf;
@@ -3174,44 +3150,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
return buf;
}
-#if 0
-int link_control(const char *name, u32 op, u32 val)
-{
- int res = -EINVAL;
- struct link *l_ptr;
- u32 bearer_id;
- struct tipc_node * node;
- u32 a;
-
- a = link_name2addr(name, &bearer_id);
- read_lock_bh(&tipc_net_lock);
- node = tipc_node_find(a);
- if (node) {
- tipc_node_lock(node);
- l_ptr = node->links[bearer_id];
- if (l_ptr) {
- if (op == TIPC_REMOVE_LINK) {
- struct bearer *b_ptr = l_ptr->b_ptr;
- spin_lock_bh(&b_ptr->publ.lock);
- tipc_link_delete(l_ptr);
- spin_unlock_bh(&b_ptr->publ.lock);
- }
- if (op == TIPC_CMD_BLOCK_LINK) {
- tipc_link_reset(l_ptr);
- l_ptr->blocked = 1;
- }
- if (op == TIPC_CMD_UNBLOCK_LINK) {
- l_ptr->blocked = 0;
- }
- res = 0;
- }
- tipc_node_unlock(node);
- }
- read_unlock_bh(&tipc_net_lock);
- return res;
-}
-#endif
-
/**
* tipc_link_get_max_pkt - get maximum packet size to use when sending to destination
* @dest: network address of destination node
@@ -3242,28 +3180,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
return res;
}
-#if 0
-static void link_dump_rec_queue(struct link *l_ptr)
-{
- struct sk_buff *crs;
-
- if (!l_ptr->oldest_deferred_in) {
- info("Reception queue empty\n");
- return;
- }
- info("Contents of Reception queue:\n");
- crs = l_ptr->oldest_deferred_in;
- while (crs) {
- if (crs->data == (void *)0x0000a3a3) {
- info("buffer %x invalid\n", crs);
- return;
- }
- msg_dbg(buf_msg(crs), "In rec queue:\n");
- crs = crs->next;
- }
-}
-#endif
-
static void link_dump_send_queue(struct link *l_ptr)
{
if (l_ptr->next_out) {