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: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ying Xue 2013-06-17 10:54:41 -04:00 committed by David S. Miller
parent 13a2e89873
commit 7d0ab17b74
3 changed files with 49 additions and 60 deletions

View file

@ -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;
tipc_server_stop(&cfgsrv);
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = 0;
tipc_withdraw(config_port_ref, TIPC_ZONE_SCOPE, &seq);
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);
}

View file

@ -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();

View file

@ -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) ?