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

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 @@ ...@@ -2,7 +2,7 @@
* net/tipc/config.c: TIPC configuration management code * net/tipc/config.c: TIPC configuration management code
* *
* Copyright (c) 2002-2006, Ericsson AB * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -38,12 +38,12 @@ ...@@ -38,12 +38,12 @@
#include "port.h" #include "port.h"
#include "name_table.h" #include "name_table.h"
#include "config.h" #include "config.h"
#include "server.h"
#define REPLY_TRUNCATED "<truncated>\n" #define REPLY_TRUNCATED "<truncated>\n"
static u32 config_port_ref;
static DEFINE_SPINLOCK(config_lock); static DEFINE_SPINLOCK(config_lock);
static struct tipc_server cfgsrv;
static const void *req_tlv_area; /* request message TLV area */ static const void *req_tlv_area; /* request message TLV area */
static int req_tlv_space; /* request message TLV area size */ static int req_tlv_space; /* request message TLV area size */
...@@ -381,33 +381,27 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area ...@@ -381,33 +381,27 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
return rep_tlv_buf; return rep_tlv_buf;
} }
static void cfg_named_msg_event(void *userdata, static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
u32 port_ref, void *usr_data, void *buf, size_t len)
struct sk_buff **buf,
const unchar *msg,
u32 size,
u32 importance,
struct tipc_portid const *orig,
struct tipc_name_seq const *dest)
{ {
struct tipc_cfg_msg_hdr *req_hdr; struct tipc_cfg_msg_hdr *req_hdr;
struct tipc_cfg_msg_hdr *rep_hdr; struct tipc_cfg_msg_hdr *rep_hdr;
struct sk_buff *rep_buf; struct sk_buff *rep_buf;
int ret;
/* Validate configuration message header (ignore invalid message) */ /* Validate configuration message header (ignore invalid message) */
req_hdr = (struct tipc_cfg_msg_hdr *)msg; req_hdr = (struct tipc_cfg_msg_hdr *)buf;
if ((size < sizeof(*req_hdr)) || if ((len < sizeof(*req_hdr)) ||
(size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || (len != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
(ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
pr_warn("Invalid configuration message discarded\n"); pr_warn("Invalid configuration message discarded\n");
return; return;
} }
/* Generate reply for request (if can't, return request) */ /* Generate reply for request (if can't, return request) */
rep_buf = tipc_cfg_do_cmd(orig->node, rep_buf = tipc_cfg_do_cmd(addr->addr.id.node, ntohs(req_hdr->tcm_type),
ntohs(req_hdr->tcm_type), buf + sizeof(*req_hdr),
msg + sizeof(*req_hdr), len - sizeof(*req_hdr),
size - sizeof(*req_hdr),
BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr)); BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
if (rep_buf) { if (rep_buf) {
skb_push(rep_buf, sizeof(*rep_hdr)); skb_push(rep_buf, sizeof(*rep_hdr));
...@@ -415,57 +409,51 @@ static void cfg_named_msg_event(void *userdata, ...@@ -415,57 +409,51 @@ static void cfg_named_msg_event(void *userdata,
memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
rep_hdr->tcm_len = htonl(rep_buf->len); rep_hdr->tcm_len = htonl(rep_buf->len);
rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); 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) */ ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len); 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) int tipc_cfg_init(void)
{ {
struct tipc_name_seq seq; return tipc_server_start(&cfgsrv);
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;
} }
void tipc_cfg_reinit(void) void tipc_cfg_reinit(void)
{ {
struct tipc_name_seq seq; tipc_server_stop(&cfgsrv);
int res;
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; cfgsrv_addr.addr.nameseq.lower = tipc_own_addr;
res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq); cfgsrv_addr.addr.nameseq.upper = tipc_own_addr;
if (res) tipc_server_start(&cfgsrv);
pr_err("Unable to reinitialize configuration service\n");
} }
void tipc_cfg_stop(void) void tipc_cfg_stop(void)
{ {
tipc_deleteport(config_port_ref); tipc_server_stop(&cfgsrv);
config_port_ref = 0;
} }
...@@ -136,8 +136,6 @@ static int tipc_core_start(void) ...@@ -136,8 +136,6 @@ static int tipc_core_start(void)
res = tipc_ref_table_init(tipc_max_ports, tipc_random); res = tipc_ref_table_init(tipc_max_ports, tipc_random);
if (!res) if (!res)
res = tipc_nametbl_init(); res = tipc_nametbl_init();
if (!res)
res = tipc_cfg_init();
if (!res) if (!res)
res = tipc_netlink_start(); res = tipc_netlink_start();
if (!res) if (!res)
...@@ -146,6 +144,8 @@ static int tipc_core_start(void) ...@@ -146,6 +144,8 @@ static int tipc_core_start(void)
res = tipc_register_sysctl(); res = tipc_register_sysctl();
if (!res) if (!res)
res = tipc_subscr_start(); res = tipc_subscr_start();
if (!res)
res = tipc_cfg_init();
if (res) if (res)
tipc_core_stop(); tipc_core_stop();
......
...@@ -403,7 +403,8 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) ...@@ -403,7 +403,8 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && 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 -EACCES;
return (addr->scope > 0) ? 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