summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/bcast.c12
-rw-r--r--net/tipc/bearer.c5
-rw-r--r--net/tipc/config.c21
-rw-r--r--net/tipc/core.c10
-rw-r--r--net/tipc/core.h42
-rw-r--r--net/tipc/discover.c79
-rw-r--r--net/tipc/link.c173
-rw-r--r--net/tipc/log.c2
-rw-r--r--net/tipc/msg.c2
-rw-r--r--net/tipc/msg.h15
-rw-r--r--net/tipc/name_distr.c4
-rw-r--r--net/tipc/name_table.c48
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c11
-rw-r--r--net/tipc/node.c70
-rw-r--r--net/tipc/node.h19
-rw-r--r--net/tipc/port.c67
-rw-r--r--net/tipc/port.h42
-rw-r--r--net/tipc/socket.c11
-rw-r--r--net/tipc/subscr.c2
20 files changed, 288 insertions, 349 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 41ecf313073c..e00441a2092f 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -256,7 +256,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
if (bcbuf_acks(crs) == 0) {
bcl->first_out = next;
bcl->out_queue_size--;
- buf_discard(crs);
+ kfree_skb(crs);
released = 1;
}
crs = next;
@@ -330,7 +330,7 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
tipc_bearer_send(&bcbearer->bearer, buf, NULL);
bcl->stats.sent_nacks++;
spin_unlock_bh(&bc_lock);
- buf_discard(buf);
+ kfree_skb(buf);
n_ptr->bclink.oos_state++;
}
@@ -374,7 +374,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
if (!bclink->bcast_nodes.count) {
res = msg_data_sz(buf_msg(buf));
- buf_discard(buf);
+ kfree_skb(buf);
goto exit;
}
@@ -480,7 +480,7 @@ receive:
if (likely(msg_mcast(msg)))
tipc_port_recv_mcast(buf, NULL);
else
- buf_discard(buf);
+ kfree_skb(buf);
} else if (msg_user(msg) == MSG_BUNDLER) {
spin_lock_bh(&bc_lock);
bclink_accept_pkt(node, seqno);
@@ -513,7 +513,7 @@ receive:
bclink_accept_pkt(node, seqno);
spin_unlock_bh(&bc_lock);
tipc_node_unlock(node);
- buf_discard(buf);
+ kfree_skb(buf);
}
buf = NULL;
@@ -569,7 +569,7 @@ receive:
unlock:
tipc_node_unlock(node);
exit:
- buf_discard(buf);
+ kfree_skb(buf);
}
u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 329fb659fae4..5dfd89c40429 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -435,7 +435,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
u32 i;
int res = -EINVAL;
- if (tipc_mode != TIPC_NET_MODE) {
+ if (!tipc_own_addr) {
warn("Bearer <%s> rejected, not supported in standalone mode\n",
name);
return -ENOPROTOOPT;
@@ -456,8 +456,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
warn("Bearer <%s> rejected, illegal discovery domain\n", name);
return -EINVAL;
}
- if ((priority < TIPC_MIN_LINK_PRI ||
- priority > TIPC_MAX_LINK_PRI) &&
+ if ((priority > TIPC_MAX_LINK_PRI) &&
(priority != TIPC_MEDIA_LINK_PRI)) {
warn("Bearer <%s> rejected, illegal priority\n", name);
return -EINVAL;
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 4785bf26cdf4..f76d3b15e4e2 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -179,7 +179,7 @@ static struct sk_buff *cfg_set_own_addr(void)
if (!tipc_addr_node_valid(addr))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (node address)");
- if (tipc_mode == TIPC_NET_MODE)
+ if (tipc_own_addr)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change node address once assigned)");
@@ -218,7 +218,7 @@ static struct sk_buff *cfg_set_max_publications(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value != delimit(value, 1, 65535))
+ if (value < 1 || value > 65535)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max publications must be 1-65535)");
tipc_max_publications = value;
@@ -233,7 +233,7 @@ static struct sk_buff *cfg_set_max_subscriptions(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value != delimit(value, 1, 65535))
+ if (value < 1 || value > 65535)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max subscriptions must be 1-65535");
tipc_max_subscriptions = value;
@@ -249,14 +249,11 @@ static struct sk_buff *cfg_set_max_ports(void)
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
if (value == tipc_max_ports)
return tipc_cfg_reply_none();
- if (value != delimit(value, 127, 65535))
+ if (value < 127 || value > 65535)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max ports must be 127-65535)");
- if (tipc_mode != TIPC_NOT_RUNNING)
- return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
- " (cannot change max ports while TIPC is active)");
- tipc_max_ports = value;
- return tipc_cfg_reply_none();
+ return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+ " (cannot change max ports while TIPC is active)");
}
static struct sk_buff *cfg_set_netid(void)
@@ -268,10 +265,10 @@ static struct sk_buff *cfg_set_netid(void)
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
if (value == tipc_net_id)
return tipc_cfg_reply_none();
- if (value != delimit(value, 1, 9999))
+ if (value < 1 || value > 9999)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network id must be 1-9999)");
- if (tipc_mode == TIPC_NET_MODE)
+ if (tipc_own_addr)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change network id once TIPC has joined a network)");
tipc_net_id = value;
@@ -481,7 +478,7 @@ int tipc_cfg_init(void)
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = tipc_own_addr;
- res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
+ res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
goto failed;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 2691cd57b8a8..68eba03e7955 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -53,7 +53,6 @@
/* global variables used by multiple sub-systems within TIPC */
-int tipc_mode = TIPC_NOT_RUNNING;
int tipc_random;
const char tipc_alphabet[] =
@@ -125,11 +124,6 @@ int tipc_core_start_net(unsigned long addr)
static void tipc_core_stop(void)
{
- if (tipc_mode != TIPC_NODE_MODE)
- return;
-
- tipc_mode = TIPC_NOT_RUNNING;
-
tipc_netlink_stop();
tipc_handler_stop();
tipc_cfg_stop();
@@ -148,11 +142,7 @@ static int tipc_core_start(void)
{
int res;
- if (tipc_mode != TIPC_NOT_RUNNING)
- return -ENOPROTOOPT;
-
get_random_bytes(&tipc_random, sizeof(tipc_random));
- tipc_mode = TIPC_NODE_MODE;
res = tipc_handler_start();
if (!res)
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 2761af36d141..13837e0e56b1 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -130,13 +130,6 @@ void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
/*
- * TIPC operating mode routines
- */
-#define TIPC_NOT_RUNNING 0
-#define TIPC_NODE_MODE 1
-#define TIPC_NET_MODE 2
-
-/*
* Global configuration variables
*/
@@ -151,7 +144,6 @@ extern int tipc_remote_management;
* Other global variables
*/
-extern int tipc_mode;
extern int tipc_random;
extern const char tipc_alphabet[];
@@ -168,16 +160,6 @@ extern void tipc_netlink_stop(void);
extern int tipc_socket_init(void);
extern void tipc_socket_stop(void);
-static inline int delimit(int val, int min, int max)
-{
- if (val > max)
- return max;
- if (val < min)
- return min;
- return val;
-}
-
-
/*
* TIPC timer and signal code
*/
@@ -279,28 +261,4 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
extern struct sk_buff *tipc_buf_acquire(u32 size);
-/**
- * buf_discard - frees a TIPC message buffer
- * @skb: message buffer
- *
- * Frees a message buffer. If passed NULL, just returns.
- */
-
-static inline void buf_discard(struct sk_buff *skb)
-{
- kfree_skb(skb);
-}
-
-/**
- * buf_linearize - convert a TIPC message buffer into a single contiguous piece
- * @skb: message buffer
- *
- * Returns 0 on success.
- */
-
-static inline int buf_linearize(struct sk_buff *skb)
-{
- return skb_linearize(skb);
-}
-
#endif
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index a00e5f811569..c630a21b2bed 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -82,6 +82,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
msg = buf_msg(buf);
tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
msg_set_non_seq(msg, 1);
+ msg_set_node_sig(msg, tipc_random);
msg_set_dest_domain(msg, dest_domain);
msg_set_bc_netid(msg, tipc_net_id);
b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
@@ -121,20 +122,22 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
{
struct tipc_node *n_ptr;
struct tipc_link *link;
- struct tipc_media_addr media_addr, *addr;
+ struct tipc_media_addr media_addr;
struct sk_buff *rbuf;
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);
+ u32 signature = msg_node_sig(msg);
+ int addr_mismatch;
int link_fully_up;
media_addr.broadcast = 1;
b_ptr->media->msg2addr(&media_addr, msg_media_addr(msg));
- buf_discard(buf);
+ kfree_skb(buf);
- /* Validate discovery message from requesting node */
+ /* Ensure message from node is valid and communication is permitted */
if (net_id != tipc_net_id)
return;
if (media_addr.broadcast)
@@ -162,15 +165,50 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
}
tipc_node_lock(n_ptr);
+ /* Prepare to validate requesting node's signature and media address */
link = n_ptr->links[b_ptr->identity];
+ addr_mismatch = (link != NULL) &&
+ memcmp(&link->media_addr, &media_addr, sizeof(media_addr));
- /* Create a link endpoint for this bearer, if necessary */
- if (!link) {
- link = tipc_link_create(n_ptr, b_ptr, &media_addr);
- if (!link) {
+ /*
+ * Ensure discovery message's signature is correct
+ *
+ * If signature is incorrect and there is no working link to the node,
+ * accept the new signature but invalidate all existing links to the
+ * node so they won't re-activate without a new discovery message.
+ *
+ * If signature is incorrect and the requested link to the node is
+ * working, accept the new signature. (This is an instance of delayed
+ * rediscovery, where a link endpoint was able to re-establish contact
+ * with its peer endpoint on a node that rebooted before receiving a
+ * discovery message from that node.)
+ *
+ * If signature is incorrect and there is a working link to the node
+ * that is not the requested link, reject the request (must be from
+ * a duplicate node).
+ */
+ if (signature != n_ptr->signature) {
+ if (n_ptr->working_links == 0) {
+ struct tipc_link *curr_link;
+ int i;
+
+ for (i = 0; i < MAX_BEARERS; i++) {
+ curr_link = n_ptr->links[i];
+ if (curr_link) {
+ memset(&curr_link->media_addr, 0,
+ sizeof(media_addr));
+ tipc_link_reset(curr_link);
+ }
+ }
+ addr_mismatch = (link != NULL);
+ } else if (tipc_link_is_up(link) && !addr_mismatch) {
+ /* delayed rediscovery */
+ } else {
+ disc_dupl_alert(b_ptr, orig, &media_addr);
tipc_node_unlock(n_ptr);
return;
}
+ n_ptr->signature = signature;
}
/*
@@ -183,17 +221,26 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
* the new media address and reset the link to ensure it starts up
* cleanly.
*/
- addr = &link->media_addr;
- if (memcmp(addr, &media_addr, sizeof(*addr))) {
- if (tipc_link_is_up(link) || (!link->started)) {
+
+ if (addr_mismatch) {
+ if (tipc_link_is_up(link)) {
disc_dupl_alert(b_ptr, orig, &media_addr);
tipc_node_unlock(n_ptr);
return;
+ } else {
+ memcpy(&link->media_addr, &media_addr,
+ sizeof(media_addr));
+ tipc_link_reset(link);
+ }
+ }
+
+ /* Create a link endpoint for this bearer, if necessary */
+ if (!link) {
+ link = tipc_link_create(n_ptr, b_ptr, &media_addr);
+ if (!link) {
+ tipc_node_unlock(n_ptr);
+ return;
}
- warn("Resetting link <%s>, peer interface address changed\n",
- link->name);
- memcpy(addr, &media_addr, sizeof(*addr));
- tipc_link_reset(link);
}
/* Accept discovery message & send response, if necessary */
@@ -203,7 +250,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr);
if (rbuf) {
b_ptr->media->send_msg(rbuf, b_ptr, &media_addr);
- buf_discard(rbuf);
+ kfree_skb(rbuf);
}
}
@@ -349,7 +396,7 @@ void tipc_disc_delete(struct tipc_link_req *req)
{
k_cancel_timer(&req->timer);
k_term_timer(&req->timer);
- buf_discard(req->buf);
+ kfree_skb(req->buf);
kfree(req);
}
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d8b0a22367b6..b4b9b30167a3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -484,7 +484,7 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
while (buf) {
next = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
}
l_ptr->first_out = NULL;
@@ -503,7 +503,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
while (buf) {
next = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
}
l_ptr->defragm_buf = NULL;
@@ -522,20 +522,20 @@ void tipc_link_stop(struct tipc_link *l_ptr)
buf = l_ptr->oldest_deferred_in;
while (buf) {
next = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
}
buf = l_ptr->first_out;
while (buf) {
next = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
}
tipc_link_reset_fragments(l_ptr);
- buf_discard(l_ptr->proto_msg_queue);
+ kfree_skb(l_ptr->proto_msg_queue);
l_ptr->proto_msg_queue = NULL;
}
@@ -571,12 +571,12 @@ void tipc_link_reset(struct tipc_link *l_ptr)
/* Clean up all queues: */
link_release_outqueue(l_ptr);
- buf_discard(l_ptr->proto_msg_queue);
+ kfree_skb(l_ptr->proto_msg_queue);
l_ptr->proto_msg_queue = NULL;
buf = l_ptr->oldest_deferred_in;
while (buf) {
struct sk_buff *next = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
}
if (!list_empty(&l_ptr->waiting_ports))
@@ -810,7 +810,7 @@ static int link_bundle_buf(struct tipc_link *l_ptr,
skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size);
msg_set_size(bundler_msg, to_pos + size);
msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
- buf_discard(buf);
+ kfree_skb(buf);
l_ptr->stats.sent_bundled++;
return 1;
}
@@ -871,17 +871,15 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
u32 queue_limit = l_ptr->queue_limit[imp];
u32 max_packet = l_ptr->max_pkt;
- msg_set_prevnode(msg, tipc_own_addr); /* If routed message */
-
/* Match msg importance against queue limits: */
if (unlikely(queue_size >= queue_limit)) {
if (imp <= TIPC_CRITICAL_IMPORTANCE) {
link_schedule_port(l_ptr, msg_origport(msg), size);
- buf_discard(buf);
+ kfree_skb(buf);
return -ELINKCONG;
}
- buf_discard(buf);
+ kfree_skb(buf);
if (imp > CONN_MANAGER) {
warn("Resetting link <%s>, send queue full", l_ptr->name);
tipc_link_reset(l_ptr);
@@ -968,10 +966,10 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
if (l_ptr)
res = tipc_link_send_buf(l_ptr, buf);
else
- buf_discard(buf);
+ kfree_skb(buf);
tipc_node_unlock(n_ptr);
} else {
- buf_discard(buf);
+ kfree_skb(buf);
}
read_unlock_bh(&tipc_net_lock);
return res;
@@ -1018,7 +1016,7 @@ void tipc_link_send_names(struct list_head *message_list, u32 dest)
list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
list_del((struct list_head *)buf);
- buf_discard(buf);
+ kfree_skb(buf);
}
}
@@ -1262,7 +1260,7 @@ again:
error:
for (; buf_chain; buf_chain = buf) {
buf = buf_chain->next;
- buf_discard(buf_chain);
+ kfree_skb(buf_chain);
}
return -EFAULT;
}
@@ -1316,7 +1314,7 @@ error:
tipc_node_unlock(node);
for (; buf_chain; buf_chain = buf) {
buf = buf_chain->next;
- buf_discard(buf_chain);
+ kfree_skb(buf_chain);
}
goto again;
}
@@ -1324,7 +1322,7 @@ error:
reject:
for (; buf_chain; buf_chain = buf) {
buf = buf_chain->next;
- buf_discard(buf_chain);
+ kfree_skb(buf_chain);
}
return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
total_len, TIPC_ERR_NO_NODE);
@@ -1390,7 +1388,7 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr)
msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
l_ptr->unacked_window = 0;
- buf_discard(buf);
+ kfree_skb(buf);
l_ptr->proto_msg_queue = NULL;
return 0;
} else {
@@ -1679,7 +1677,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Ensure message data is a single contiguous unit */
- if (unlikely(buf_linearize(buf)))
+ if (unlikely(skb_linearize(buf)))
goto cont;
/* Handle arrival of a non-unicast link message */
@@ -1744,7 +1742,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
less_eq(buf_seqno(crs), ackd)) {
struct sk_buff *next = crs->next;
- buf_discard(crs);
+ kfree_skb(crs);
crs = next;
released++;
}
@@ -1773,57 +1771,56 @@ protocol_check:
if (unlikely(l_ptr->oldest_deferred_in))
head = link_insert_deferred_queue(l_ptr,
head);
- if (likely(msg_is_dest(msg, tipc_own_addr))) {
- int ret;
deliver:
- if (likely(msg_isdata(msg))) {
- tipc_node_unlock(n_ptr);
- tipc_port_recv_msg(buf);
- continue;
+ if (likely(msg_isdata(msg))) {
+ tipc_node_unlock(n_ptr);
+ tipc_port_recv_msg(buf);
+ continue;
+ }
+ switch (msg_user(msg)) {
+ int ret;
+ case MSG_BUNDLER:
+ l_ptr->stats.recv_bundles++;
+ l_ptr->stats.recv_bundled +=
+ msg_msgcnt(msg);
+ tipc_node_unlock(n_ptr);
+ tipc_link_recv_bundle(buf);
+ continue;
+ case NAME_DISTRIBUTOR:
+ tipc_node_unlock(n_ptr);
+ tipc_named_recv(buf);
+ continue;
+ case CONN_MANAGER:
+ tipc_node_unlock(n_ptr);
+ tipc_port_recv_proto_msg(buf);
+ continue;
+ case MSG_FRAGMENTER:
+ l_ptr->stats.recv_fragments++;
+ ret = tipc_link_recv_fragment(
+ &l_ptr->defragm_buf,
+ &buf, &msg);
+ if (ret == 1) {
+ l_ptr->stats.recv_fragmented++;
+ goto deliver;
}
- switch (msg_user(msg)) {
- case MSG_BUNDLER:
- l_ptr->stats.recv_bundles++;
- l_ptr->stats.recv_bundled +=
- msg_msgcnt(msg);
- tipc_node_unlock(n_ptr);
- tipc_link_recv_bundle(buf);
- continue;
- case NAME_DISTRIBUTOR:
- tipc_node_unlock(n_ptr);
- tipc_named_recv(buf);
- continue;
- case CONN_MANAGER:
- tipc_node_unlock(n_ptr);
- tipc_port_recv_proto_msg(buf);
- continue;
- case MSG_FRAGMENTER:
- l_ptr->stats.recv_fragments++;
- ret = tipc_link_recv_fragment(
- &l_ptr->defragm_buf,
- &buf, &msg);
- if (ret == 1) {
- l_ptr->stats.recv_fragmented++;
+ if (ret == -1)
+ l_ptr->next_in_no--;
+ break;
+ case CHANGEOVER_PROTOCOL:
+ type = msg_type(msg);
+ if (link_recv_changeover_msg(&l_ptr,
+ &buf)) {
+ msg = buf_msg(buf);
+ seq_no = msg_seqno(msg);
+ if (type == ORIGINAL_MSG)
goto deliver;
- }
- if (ret == -1)
- l_ptr->next_in_no--;
- break;
- case CHANGEOVER_PROTOCOL:
- type = msg_type(msg);
- if (link_recv_changeover_msg(&l_ptr, &buf)) {
- msg = buf_msg(buf);
- seq_no = msg_seqno(msg);
- if (type == ORIGINAL_MSG)
- goto deliver;
- goto protocol_check;
- }
- break;
- default:
- buf_discard(buf);
- buf = NULL;
- break;
+ goto protocol_check;
}
+ break;
+ default:
+ kfree_skb(buf);
+ buf = NULL;
+ break;
}
tipc_node_unlock(n_ptr);
tipc_net_route_msg(buf);
@@ -1852,7 +1849,7 @@ deliver:
}
tipc_node_unlock(n_ptr);
cont:
- buf_discard(buf);
+ kfree_skb(buf);
}
read_unlock_bh(&tipc_net_lock);
}
@@ -1892,7 +1889,7 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
u32 curr_seqno = buf_seqno(queue_buf);
if (seq_no == curr_seqno) {
- buf_discard(buf);
+ kfree_skb(buf);
return 0;
}
@@ -1933,7 +1930,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
if (less(seq_no, mod(l_ptr->next_in_no))) {
l_ptr->stats.duplicates++;
- buf_discard(buf);
+ kfree_skb(buf);
return;
}
@@ -1962,7 +1959,7 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
/* Discard any previous message that was deferred due to congestion */
if (l_ptr->proto_msg_queue) {
- buf_discard(l_ptr->proto_msg_queue);
+ kfree_skb(l_ptr->proto_msg_queue);
l_ptr->proto_msg_queue = NULL;
}
@@ -2061,7 +2058,7 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
/* Discard message if it was sent successfully */
l_ptr->unacked_window = 0;
- buf_discard(buf);
+ kfree_skb(buf);
}
/*
@@ -2205,7 +2202,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
break;
}
exit:
- buf_discard(buf);
+ kfree_skb(buf);
}
@@ -2403,7 +2400,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
warn("Link changeover error, duplicate msg dropped\n");
goto exit;
}
- buf_discard(tunnel_buf);
+ kfree_skb(tunnel_buf);
return 1;
}
@@ -2435,7 +2432,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
} else {
*buf = buf_extract(tunnel_buf, INT_H_SIZE);
if (*buf != NULL) {
- buf_discard(tunnel_buf);
+ kfree_skb(tunnel_buf);
return 1;
} else {
warn("Link changeover error, original msg dropped\n");
@@ -2443,7 +2440,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
}
exit:
*buf = NULL;
- buf_discard(tunnel_buf);
+ kfree_skb(tunnel_buf);
return 0;
}
@@ -2465,7 +2462,7 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
pos += align(msg_size(buf_msg(obuf)));
tipc_net_route_msg(obuf);
}
- buf_discard(buf);
+ kfree_skb(buf);
}
/*
@@ -2514,11 +2511,11 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
}
fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (fragm == NULL) {
- buf_discard(buf);
+ kfree_skb(buf);
while (buf_chain) {
buf = buf_chain;
buf_chain = buf_chain->next;
- buf_discard(buf);
+ kfree_skb(buf);
}
return -ENOMEM;
}
@@ -2535,7 +2532,7 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
crs += fragm_sz;
msg_set_type(&fragm_hdr, FRAGMENT);
}
- buf_discard(buf);
+ kfree_skb(buf);
/* Append chain of fragments to send queue & send them */
@@ -2622,7 +2619,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
if (msg_type(imsg) == TIPC_MCAST_MSG)
max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
if (msg_size(imsg) > max) {
- buf_discard(fbuf);
+ kfree_skb(fbuf);
return 0;
}
pbuf = tipc_buf_acquire(msg_size(imsg));
@@ -2638,10 +2635,10 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
set_expected_frags(pbuf, exp_fragm_cnt - 1);
} else {
dbg("Link unable to reassemble fragmented message\n");
- buf_discard(fbuf);
+ kfree_skb(fbuf);
return -1;
}
- buf_discard(fbuf);
+ kfree_skb(fbuf);
return 0;
} else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) {
u32 dsz = msg_data_sz(fragm);
@@ -2650,7 +2647,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
u32 exp_frags = get_expected_frags(pbuf) - 1;
skb_copy_to_linear_data_offset(pbuf, crs,
msg_data(fragm), dsz);
- buf_discard(fbuf);
+ kfree_skb(fbuf);
/* Is message complete? */
@@ -2667,7 +2664,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
set_expected_frags(pbuf, exp_frags);
return 0;
}
- buf_discard(fbuf);
+ kfree_skb(fbuf);
return 0;
}
@@ -2698,7 +2695,7 @@ static void link_check_defragm_bufs(struct tipc_link *l_ptr)
prev->next = buf->next;
else
l_ptr->defragm_buf = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
}
buf = next;
}
@@ -3073,7 +3070,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area),
(char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO);
if (!str_len) {
- buf_discard(buf);
+ kfree_skb(buf);
return tipc_cfg_reply_error_string("link not found");
}
diff --git a/net/tipc/log.c b/net/tipc/log.c
index 952c39f643e6..895c6e530b0b 100644
--- a/net/tipc/log.c
+++ b/net/tipc/log.c
@@ -304,7 +304,7 @@ struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
- if (value != delimit(value, 0, 32768))
+ if (value > 32768)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (log size must be 0-32768)");
if (tipc_log_resize(value))
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 3e4d3e29be61..e3afe162c0ac 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -106,7 +106,7 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
if (likely(res))
return dsz;
- buf_discard(*buf);
+ kfree_skb(*buf);
*buf = NULL;
return -EFAULT;
}
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 7b0cda167107..eba524e34a6b 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -384,11 +384,6 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
msg_set_word(m, 7, a);
}
-static inline int msg_is_dest(struct tipc_msg *m, u32 d)
-{
- return msg_short(m) || (msg_destnode(m) == d);
-}
-
static inline u32 msg_nametype(struct tipc_msg *m)
{
return msg_word(m, 8);
@@ -517,6 +512,16 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
msg_set_bits(m, 1, 16, 0x1fff, n);
}
+static inline u32 msg_node_sig(struct tipc_msg *m)
+{
+ return msg_bits(m, 1, 0, 0xffff);
+}
+
+static inline void msg_set_node_sig(struct tipc_msg *m, u32 n)
+{
+ msg_set_bits(m, 1, 0, 0xffff, n);
+}
+
/*
* Word 2
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index acecfda82f37..d57da6159616 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -120,7 +120,7 @@ static void named_cluster_distribute(struct sk_buff *buf)
}
}
- buf_discard(buf);
+ kfree_skb(buf);
}
/**
@@ -312,7 +312,7 @@ void tipc_named_recv(struct sk_buff *buf)
item++;
}
write_unlock_bh(&tipc_nametbl_lock);
- buf_discard(buf);
+ kfree_skb(buf);
}
/**
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 89eb5621ebba..c6a1ae36952e 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -114,10 +114,8 @@ struct name_table {
};
static struct name_table table;
-static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
DEFINE_RWLOCK(tipc_nametbl_lock);
-
static int hash(int x)
{
return x & (tipc_nametbl_size - 1);
@@ -270,6 +268,13 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
}
info = sseq->info;
+
+ /* Check if an identical publication already exists */
+ list_for_each_entry(publ, &info->zone_list, zone_list) {
+ if ((publ->ref == port) && (publ->key == key) &&
+ (!publ->node || (publ->node == node)))
+ return NULL;
+ }
} else {
u32 inspos;
struct sub_seq *freesseq;
@@ -534,10 +539,17 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
}
/*
- * tipc_nametbl_translate - translate name to port id
+ * tipc_nametbl_translate - perform name translation
+ *
+ * On entry, 'destnode' is the search domain used during translation.
*
- * Note: on entry 'destnode' is the search domain used during translation;
- * on exit it passes back the node address of the matching port (if any)
+ * On exit:
+ * - if name translation is deferred to another node/cluster/zone,
+ * leaves 'destnode' unchanged (will be non-zero) and returns 0
+ * - if name translation is attempted and succeeds, sets 'destnode'
+ * to publishing node and returns port reference (will be non-zero)
+ * - if name translation is attempted and fails, sets 'destnode' to 0
+ * and returns 0
*/
u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
@@ -547,6 +559,7 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
struct publication *publ;
struct name_seq *seq;
u32 ref = 0;
+ u32 node = 0;
if (!tipc_in_scope(*destnode, tipc_own_addr))
return 0;
@@ -604,11 +617,12 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
}
ref = publ->ref;
- *destnode = publ->node;
+ node = publ->node;
no_match:
spin_unlock_bh(&seq->lock);
not_found:
read_unlock_bh(&tipc_nametbl_lock);
+ *destnode = node;
return ref;
}
@@ -665,22 +679,7 @@ exit:
return res;
}
-/**
- * tipc_nametbl_publish_rsv - publish port name using a reserved name type
- */
-
-int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope,
- struct tipc_name_seq const *seq)
-{
- int res;
-
- atomic_inc(&rsv_publ_ok);
- res = tipc_publish(ref, scope, seq);
- atomic_dec(&rsv_publ_ok);
- return res;
-}
-
-/**
+/*
* tipc_nametbl_publish - add name publication to network name tables
*/
@@ -694,11 +693,6 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
tipc_max_publications);
return NULL;
}
- if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) {
- warn("Publication failed, reserved name {%u,%u,%u}\n",
- type, lower, upper);
- return NULL;
- }
write_lock_bh(&tipc_nametbl_lock);
table.local_publ_count++;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 8086b42f92ad..207d59ebf849 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -91,8 +91,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
struct tipc_port_list *dports);
-int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope,
- struct tipc_name_seq const *seq);
struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
u32 scope, u32 port_ref, u32 key);
int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 61afee7e8291..d4531b07076c 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -117,7 +117,7 @@ static void net_route_named_msg(struct sk_buff *buf)
u32 dport;
if (!msg_named(msg)) {
- buf_discard(buf);
+ kfree_skb(buf);
return;
}
@@ -161,7 +161,7 @@ void tipc_net_route_msg(struct sk_buff *buf)
tipc_port_recv_proto_msg(buf);
break;
default:
- buf_discard(buf);
+ kfree_skb(buf);
}
return;
}
@@ -175,14 +175,10 @@ int tipc_net_start(u32 addr)
{
char addr_string[16];
- if (tipc_mode != TIPC_NODE_MODE)
- return -ENOPROTOOPT;
-
tipc_subscr_stop();
tipc_cfg_stop();
tipc_own_addr = addr;
- tipc_mode = TIPC_NET_MODE;
tipc_named_reinit();
tipc_port_reinit();
@@ -201,10 +197,9 @@ void tipc_net_stop(void)
{
struct tipc_node *node, *t_node;
- if (tipc_mode != TIPC_NET_MODE)
+ if (!tipc_own_addr)
return;
write_lock_bh(&tipc_net_lock);
- tipc_mode = TIPC_NODE_MODE;
tipc_bearer_stop();
tipc_bclink_stop();
list_for_each_entry_safe(node, t_node, &tipc_node_list, list)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 7bc45e135fb4..a34cabc2c43a 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -39,6 +39,8 @@
#include "node.h"
#include "name_distr.h"
+#define NODE_HTABLE_SIZE 512
+
static void node_lost_contact(struct tipc_node *n_ptr);
static void node_established_contact(struct tipc_node *n_ptr);
@@ -51,6 +53,17 @@ static u32 tipc_num_nodes;
static atomic_t tipc_num_links = ATOMIC_INIT(0);
/*
+ * A trivial power-of-two bitmask technique is used for speed, since this
+ * operation is done for every incoming TIPC packet. The number of hash table
+ * entries has been chosen so that no hash chain exceeds 8 nodes and will
+ * usually be much smaller (typically only a single node).
+ */
+static inline unsigned int tipc_hashfn(u32 addr)
+{
+ return addr & (NODE_HTABLE_SIZE - 1);
+}
+
+/*
* tipc_node_find - locate specified node object, if it exists
*/
@@ -112,6 +125,7 @@ struct tipc_node *tipc_node_create(u32 addr)
}
list_add_tail(&n_ptr->list, &temp_node->list);
n_ptr->block_setup = WAIT_PEER_DOWN;
+ n_ptr->signature = INVALID_NODE_SIG;
tipc_num_nodes++;
@@ -252,60 +266,12 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
n_ptr->link_cnt--;
}
-/*
- * Routing table management - five cases to handle:
- *
- * 1: A link towards a zone/cluster external node comes up.
- * => Send a multicast message updating routing tables of all
- * system nodes within own cluster that the new destination
- * can be reached via this node.
- * (node.establishedContact()=>cluster.multicastNewRoute())
- *
- * 2: A link towards a slave node comes up.
- * => Send a multicast message updating routing tables of all
- * system nodes within own cluster that the new destination
- * can be reached via this node.
- * (node.establishedContact()=>cluster.multicastNewRoute())
- * => Send a message to the slave node about existence
- * of all system nodes within cluster:
- * (node.establishedContact()=>cluster.sendLocalRoutes())
- *
- * 3: A new cluster local system node becomes available.
- * => Send message(s) to this particular node containing
- * information about all cluster external and slave
- * nodes which can be reached via this node.
- * (node.establishedContact()==>network.sendExternalRoutes())
- * (node.establishedContact()==>network.sendSlaveRoutes())
- * => Send messages to all directly connected slave nodes
- * containing information about the existence of the new node
- * (node.establishedContact()=>cluster.multicastNewRoute())
- *
- * 4: The link towards a zone/cluster external node or slave
- * node goes down.
- * => Send a multcast message updating routing tables of all
- * nodes within cluster that the new destination can not any
- * longer be reached via this node.
- * (node.lostAllLinks()=>cluster.bcastLostRoute())
- *
- * 5: A cluster local system node becomes unavailable.
- * => Remove all references to this node from the local
- * routing tables. Note: This is a completely node
- * local operation.
- * (node.lostAllLinks()=>network.removeAsRouter())
- * => Send messages to all directly connected slave nodes
- * containing information about loss of the node
- * (node.establishedContact()=>cluster.multicastLostRoute())
- *
- */
-
static void node_established_contact(struct tipc_node *n_ptr)
{
tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
- /* Syncronize broadcast acks */
- n_ptr->bclink.acked = tipc_bclink_get_last_sent();
-
if (n_ptr->bclink.supportable) {
+ n_ptr->bclink.acked = tipc_bclink_get_last_sent();
tipc_bclink_add_node(n_ptr->addr);
n_ptr->bclink.supported = 1;
}
@@ -339,12 +305,12 @@ static void node_lost_contact(struct tipc_node *n_ptr)
while (n_ptr->bclink.deferred_head) {
struct sk_buff *buf = n_ptr->bclink.deferred_head;
n_ptr->bclink.deferred_head = buf->next;
- buf_discard(buf);
+ kfree_skb(buf);
}
n_ptr->bclink.deferred_size = 0;
if (n_ptr->bclink.defragm) {
- buf_discard(n_ptr->bclink.defragm);
+ kfree_skb(n_ptr->bclink.defragm);
n_ptr->bclink.defragm = NULL;
}
@@ -440,7 +406,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network address)");
- if (tipc_mode != TIPC_NET_MODE)
+ if (!tipc_own_addr)
return tipc_cfg_reply_none();
read_lock_bh(&tipc_net_lock);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index e1b78a2199c2..72561c971d67 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -42,6 +42,11 @@
#include "net.h"
#include "bearer.h"
+/*
+ * Out-of-range value for node signature
+ */
+#define INVALID_NODE_SIG 0x10000
+
/* Flags used to block (re)establishment of contact with a neighboring node */
#define WAIT_PEER_DOWN 0x0001 /* wait to see that peer's links are down */
@@ -61,6 +66,7 @@
* @block_setup: bit mask of conditions preventing link establishment to node
* @link_cnt: number of links to node
* @permit_changeover: non-zero if node has redundant links to this system
+ * @signature: node instance identifier
* @bclink: broadcast-related info
* @supportable: non-zero if node supports TIPC b'cast link capability
* @supported: non-zero if node supports TIPC b'cast capability
@@ -86,6 +92,7 @@ struct tipc_node {
int working_links;
int block_setup;
int permit_changeover;
+ u32 signature;
struct {
u8 supportable;
u8 supported;
@@ -100,20 +107,8 @@ struct tipc_node {
} bclink;
};
-#define NODE_HTABLE_SIZE 512
extern struct list_head tipc_node_list;
-/*
- * A trivial power-of-two bitmask technique is used for speed, since this
- * operation is done for every incoming TIPC packet. The number of hash table
- * entries has been chosen so that no hash chain exceeds 8 nodes and will
- * usually be much smaller (typically only a single node).
- */
-static inline unsigned int tipc_hashfn(u32 addr)
-{
- return addr & (NODE_HTABLE_SIZE - 1);
-}
-
struct tipc_node *tipc_node_find(u32 addr);
struct tipc_node *tipc_node_create(u32 addr);
void tipc_node_delete(struct tipc_node *n_ptr);
diff --git a/net/tipc/port.c b/net/tipc/port.c
index ba3268b8da42..94d2904cce66 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -116,13 +116,13 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
ibuf = skb_copy(buf, GFP_ATOMIC);
if (ibuf == NULL) {
tipc_port_list_free(&dports);
- buf_discard(buf);
+ kfree_skb(buf);
return -ENOMEM;
}
}
res = tipc_bclink_send_msg(buf);
if ((res < 0) && (dports.count != 0))
- buf_discard(ibuf);
+ kfree_skb(ibuf);
} else {
ibuf = buf;
}
@@ -187,7 +187,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp)
}
}
exit:
- buf_discard(buf);
+ kfree_skb(buf);
tipc_port_list_free(dp);
}
@@ -420,7 +420,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
else
tipc_link_send(rbuf, src_node, msg_link_selector(rmsg));
exit:
- buf_discard(buf);
+ kfree_skb(buf);
return data_sz;
}
@@ -568,7 +568,7 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
tipc_port_unlock(p_ptr);
exit:
tipc_net_route_msg(r_buf);
- buf_discard(buf);
+ kfree_skb(buf);
}
static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
@@ -759,7 +759,7 @@ static void port_dispatcher_sigh(void *dummy)
}
}
if (buf)
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
continue;
err:
@@ -813,7 +813,7 @@ err:
}
}
if (buf)
- buf_discard(buf);
+ kfree_skb(buf);
buf = next;
continue;
reject:
@@ -1054,8 +1054,6 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
msg = &p_ptr->phdr;
msg_set_destnode(msg, peer->node);
msg_set_destport(msg, peer->ref);
- msg_set_orignode(msg, tipc_own_addr);
- msg_set_origport(msg, p_ptr->ref);
msg_set_type(msg, TIPC_CONN_MSG);
msg_set_lookup_scope(msg, 0);
msg_set_hdr_sz(msg, SHORT_H_SIZE);
@@ -1133,6 +1131,49 @@ int tipc_shutdown(u32 ref)
return tipc_disconnect(ref);
}
+/**
+ * tipc_port_recv_msg - receive message from lower layer and deliver to port user
+ */
+
+int tipc_port_recv_msg(struct sk_buff *buf)
+{
+ struct tipc_port *p_ptr;
+ struct tipc_msg *msg = buf_msg(buf);
+ u32 destport = msg_destport(msg);
+ u32 dsz = msg_data_sz(msg);
+ u32 err;
+
+ /* forward unresolved named message */
+ if (unlikely(!destport)) {
+ tipc_net_route_msg(buf);
+ return dsz;
+ }
+
+ /* validate destination & pass to port, otherwise reject message */
+ p_ptr = tipc_port_lock(destport);
+ if (likely(p_ptr)) {
+ if (likely(p_ptr->connected)) {
+ if ((unlikely(msg_origport(msg) !=
+ tipc_peer_port(p_ptr))) ||
+ (unlikely(msg_orignode(msg) !=
+ tipc_peer_node(p_ptr))) ||
+ (unlikely(!msg_connected(msg)))) {
+ err = TIPC_ERR_NO_PORT;
+ tipc_port_unlock(p_ptr);
+ goto reject;
+ }
+ }
+ err = p_ptr->dispatcher(p_ptr, buf);
+ tipc_port_unlock(p_ptr);
+ if (likely(!err))
+ return dsz;
+ } else {
+ err = TIPC_ERR_NO_PORT;
+ }
+reject:
+ return tipc_reject_msg(buf, err);
+}
+
/*
* tipc_port_recv_sections(): Concatenate and deliver sectioned
* message for this node.
@@ -1211,8 +1252,6 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
msg = &p_ptr->phdr;
msg_set_type(msg, TIPC_NAMED_MSG);
- msg_set_orignode(msg, tipc_own_addr);
- msg_set_origport(msg, ref);
msg_set_hdr_sz(msg, NAMED_H_SIZE);
msg_set_nametype(msg, name->type);
msg_set_nameinst(msg, name->instance);
@@ -1221,7 +1260,7 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
msg_set_destnode(msg, destnode);
msg_set_destport(msg, destport);
- if (likely(destport)) {
+ if (likely(destport || destnode)) {
if (likely(destnode == tipc_own_addr))
res = tipc_port_recv_sections(p_ptr, num_sect,
msg_sect, total_len);
@@ -1262,8 +1301,6 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
msg = &p_ptr->phdr;
msg_set_type(msg, TIPC_DIRECT_MSG);
msg_set_lookup_scope(msg, 0);
- msg_set_orignode(msg, tipc_own_addr);
- msg_set_origport(msg, ref);
msg_set_destnode(msg, dest->node);
msg_set_destport(msg, dest->ref);
msg_set_hdr_sz(msg, BASIC_H_SIZE);
@@ -1302,8 +1339,6 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
msg = &p_ptr->phdr;
msg_set_type(msg, TIPC_DIRECT_MSG);
- msg_set_orignode(msg, tipc_own_addr);
- msg_set_origport(msg, ref);
msg_set_destnode(msg, dest->node);
msg_set_destport(msg, dest->ref);
msg_set_hdr_sz(msg, BASIC_H_SIZE);
diff --git a/net/tipc/port.h b/net/tipc/port.h
index f751807e2a91..9b88531e5a61 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -205,6 +205,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr);
/*
* TIPC messaging routines
*/
+int tipc_port_recv_msg(struct sk_buff *buf);
int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
unsigned int total_len);
@@ -271,45 +272,4 @@ static inline int tipc_port_congested(struct tipc_port *p_ptr)
return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
}
-/**
- * tipc_port_recv_msg - receive message from lower layer and deliver to port user
- */
-
-static inline int tipc_port_recv_msg(struct sk_buff *buf)
-{
- struct tipc_port *p_ptr;
- struct tipc_msg *msg = buf_msg(buf);
- u32 destport = msg_destport(msg);
- u32 dsz = msg_data_sz(msg);
- u32 err;
-
- /* forward unresolved named message */
- if (unlikely(!destport)) {
- tipc_net_route_msg(buf);
- return dsz;
- }
-
- /* validate destination & pass to port, otherwise reject message */
- p_ptr = tipc_port_lock(destport);
- if (likely(p_ptr)) {
- if (likely(p_ptr->connected)) {
- if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
- (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
- (unlikely(!msg_connected(msg)))) {
- err = TIPC_ERR_NO_PORT;
- tipc_port_unlock(p_ptr);
- goto reject;
- }
- }
- err = p_ptr->dispatcher(p_ptr, buf);
- tipc_port_unlock(p_ptr);
- if (likely(!err))
- return dsz;
- } else {
- err = TIPC_ERR_NO_PORT;
- }
-reject:
- return tipc_reject_msg(buf, err);
-}
-
#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e2f7c5d370ba..29e957f64458 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -126,7 +126,7 @@ static atomic_t tipc_queue_size = ATOMIC_INIT(0);
static void advance_rx_queue(struct sock *sk)
{
- buf_discard(__skb_dequeue(&sk->sk_receive_queue));
+ kfree_skb(__skb_dequeue(&sk->sk_receive_queue));
atomic_dec(&tipc_queue_size);
}
@@ -142,7 +142,7 @@ static void discard_rx_queue(struct sock *sk)
while ((buf = __skb_dequeue(&sk->sk_receive_queue))) {
atomic_dec(&tipc_queue_size);
- buf_discard(buf);
+ kfree_skb(buf);
}
}
@@ -288,7 +288,7 @@ static int release(struct socket *sock)
break;
atomic_dec(&tipc_queue_size);
if (TIPC_SKB_CB(buf)->handle != 0)
- buf_discard(buf);
+ kfree_skb(buf);
else {
if ((sock->state == SS_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
@@ -355,6 +355,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
else if (addr->addrtype != TIPC_ADDR_NAMESEQ)
return -EAFNOSUPPORT;
+ if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES)
+ return -EACCES;
+
return (addr->scope > 0) ?
tipc_publish(portref, addr->scope, &addr->addr.nameseq) :
tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq);
@@ -1612,7 +1615,7 @@ restart:
if (buf) {
atomic_dec(&tipc_queue_size);
if (TIPC_SKB_CB(buf)->handle != 0) {
- buf_discard(buf);
+ kfree_skb(buf);
goto restart;
}
tipc_disconnect(tport->ref);
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 8c49566da8f3..b2964e9895d3 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -552,7 +552,7 @@ int tipc_subscr_start(void)
if (res)
goto failed;
- res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
+ res = tipc_publish(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
if (res) {
tipc_deleteport(topsrv.setup_port);
topsrv.setup_port = 0;