Commit 7d0ab17b authored by Ying Xue's avatar Ying Xue Committed by David S. Miller
Browse files

tipc: convert configuration server to use new server facility



As the new socket-based TIPC server infrastructure has been
introduced, we can now convert the configuration server to use
it.  Then we can take future steps to simplify the configuration
server locking policy.

Some minor reordering of initialization is done, due to the
dependency on having tipc_socket_init completed.
Signed-off-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 13a2e898
......@@ -2,7 +2,7 @@
* net/tipc/config.c: TIPC configuration management code
*
* Copyright (c) 2002-2006, Ericsson AB
* Copyright (c) 2004-2007, 2010-2012, Wind River Systems
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -38,12 +38,12 @@
#include "port.h"
#include "name_table.h"
#include "config.h"
#include "server.h"
#define REPLY_TRUNCATED "<truncated>\n"
static u32 config_port_ref;
static DEFINE_SPINLOCK(config_lock);
static struct tipc_server cfgsrv;
static const void *req_tlv_area; /* request message TLV area */
static int req_tlv_space; /* request message TLV area size */
......@@ -381,33 +381,27 @@ exit:
return rep_tlv_buf;
}
static void cfg_named_msg_event(void *userdata,
u32 port_ref,
struct sk_buff **buf,
const unchar *msg,
u32 size,
u32 importance,
struct tipc_portid const *orig,
struct tipc_name_seq const *dest)
static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
void *usr_data, void *buf, size_t len)
{
struct tipc_cfg_msg_hdr *req_hdr;
struct tipc_cfg_msg_hdr *rep_hdr;
struct sk_buff *rep_buf;
int ret;
/* Validate configuration message header (ignore invalid message) */
req_hdr = (struct tipc_cfg_msg_hdr *)msg;
if ((size < sizeof(*req_hdr)) ||
(size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
req_hdr = (struct tipc_cfg_msg_hdr *)buf;
if ((len < sizeof(*req_hdr)) ||
(len != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
(ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
pr_warn("Invalid configuration message discarded\n");
return;
}
/* Generate reply for request (if can't, return request) */
rep_buf = tipc_cfg_do_cmd(orig->node,
ntohs(req_hdr->tcm_type),
msg + sizeof(*req_hdr),
size - sizeof(*req_hdr),
rep_buf = tipc_cfg_do_cmd(addr->addr.id.node, ntohs(req_hdr->tcm_type),
buf + sizeof(*req_hdr),
len - sizeof(*req_hdr),
BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
if (rep_buf) {
skb_push(rep_buf, sizeof(*rep_hdr));
......@@ -415,57 +409,51 @@ static void cfg_named_msg_event(void *userdata,
memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
rep_hdr->tcm_len = htonl(rep_buf->len);
rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
} else {
rep_buf = *buf;
*buf = NULL;
}
/* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */
tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
rep_buf->len);
if (ret < 0)
pr_err("Sending cfg reply message failed, no memory\n");
kfree_skb(rep_buf);
}
}
static struct sockaddr_tipc cfgsrv_addr __read_mostly = {
.family = AF_TIPC,
.addrtype = TIPC_ADDR_NAMESEQ,
.addr.nameseq.type = TIPC_CFG_SRV,
.addr.nameseq.lower = 0,
.addr.nameseq.upper = 0,
.scope = TIPC_ZONE_SCOPE
};
static struct tipc_server cfgsrv __read_mostly = {
.saddr = &cfgsrv_addr,
.imp = TIPC_CRITICAL_IMPORTANCE,
.type = SOCK_RDM,
.max_rcvbuf_size = 64 * 1024,
.name = "cfg_server",
.tipc_conn_recvmsg = cfg_conn_msg_event,
.tipc_conn_new = NULL,
.tipc_conn_shutdown = NULL
};
int tipc_cfg_init(void)
{
struct tipc_name_seq seq;
int res;
res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
NULL, NULL, NULL,
NULL, cfg_named_msg_event, NULL,
NULL, &config_port_ref);
if (res)
goto failed;
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = tipc_own_addr;
res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
goto failed;
return 0;
failed:
pr_err("Unable to create configuration service\n");
return res;
return tipc_server_start(&cfgsrv);
}
void tipc_cfg_reinit(void)
{
struct tipc_name_seq seq;
int res;
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = 0;
tipc_withdraw(config_port_ref, TIPC_ZONE_SCOPE, &seq);
tipc_server_stop(&cfgsrv);
seq.lower = seq.upper = tipc_own_addr;
res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
pr_err("Unable to reinitialize configuration service\n");
cfgsrv_addr.addr.nameseq.lower = tipc_own_addr;
cfgsrv_addr.addr.nameseq.upper = tipc_own_addr;
tipc_server_start(&cfgsrv);
}
void tipc_cfg_stop(void)
{
tipc_deleteport(config_port_ref);
config_port_ref = 0;
tipc_server_stop(&cfgsrv);
}
......@@ -136,8 +136,6 @@ static int tipc_core_start(void)
res = tipc_ref_table_init(tipc_max_ports, tipc_random);
if (!res)
res = tipc_nametbl_init();
if (!res)
res = tipc_cfg_init();
if (!res)
res = tipc_netlink_start();
if (!res)
......@@ -146,6 +144,8 @@ static int tipc_core_start(void)
res = tipc_register_sysctl();
if (!res)
res = tipc_subscr_start();
if (!res)
res = tipc_cfg_init();
if (res)
tipc_core_stop();
......
......@@ -403,7 +403,8 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
return -EAFNOSUPPORT;
if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
(addr->addr.nameseq.type != TIPC_TOP_SRV))
(addr->addr.nameseq.type != TIPC_TOP_SRV) &&
(addr->addr.nameseq.type != TIPC_CFG_SRV))
return -EACCES;
return (addr->scope > 0) ?
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment