diff options
Diffstat (limited to 'exec/totemnet.c')
-rw-r--r-- | exec/totemnet.c | 628 |
1 files changed, 628 insertions, 0 deletions
diff --git a/exec/totemnet.c b/exec/totemnet.c new file mode 100644 index 0000000..58992e6 --- /dev/null +++ b/exec/totemnet.c @@ -0,0 +1,628 @@ +/* + * Copyright (c) 2005 MontaVista Software, Inc. + * Copyright (c) 2006-2018 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> + +#include <assert.h> + +#include <totemudp.h> +#include <totemudpu.h> +#include <totemknet.h> +#include <totemnet.h> +#include <qb/qbloop.h> + +#define LOGSYS_UTILS_ONLY 1 +#include <corosync/logsys.h> + +struct transport { + const char *name; + + int (*initialize) ( + qb_loop_t *loop_pt, + void **transport_instance, + struct totem_config *totem_config, + totemsrp_stats_t *stats, + void *context, + + int (*deliver_fn) ( + void *context, + const void *msg, + unsigned int msg_len, + const struct sockaddr_storage *system_from), + + int (*iface_change_fn) ( + void *context, + const struct totem_ip_address *iface_address, + unsigned int ring_no), + + void (*mtu_changed) ( + void *context, + int net_mtu), + + void (*target_set_completed) ( + void *context)); + + void *(*buffer_alloc) (void); + + void (*buffer_release) (void *ptr); + + int (*processor_count_set) ( + void *transport_context, + int processor_count); + + int (*token_send) ( + void *transport_context, + const void *msg, + unsigned int msg_len); + + int (*mcast_flush_send) ( + void *transport_context, + const void *msg, + unsigned int msg_len); + + + int (*mcast_noflush_send) ( + void *transport_context, + const void *msg, + unsigned int msg_len); + + int (*recv_flush) (void *transport_context); + + int (*send_flush) (void *transport_context); + + int (*iface_check) (void *transport_context); + + int (*finalize) (void *transport_context); + + void (*net_mtu_adjust) (void *transport_context, struct totem_config *totem_config); + + const char *(*iface_print) (void *transport_context); + + int (*ifaces_get) ( + void *transport_context, + char ***status, + unsigned int *iface_count); + + int (*nodestatus_get) ( + void *transport_context, + unsigned int nodeid, + struct totem_node_status *node_status); + + int (*token_target_set) ( + void *transport_context, + unsigned int nodeid); + + int (*crypto_set) ( + void *transport_context, + const char *cipher_type, + const char *hash_type); + + int (*recv_mcast_empty) ( + void *transport_context); + + int (*iface_set) ( + void *transport_context, + const struct totem_ip_address *local, + unsigned short ip_port, + unsigned int ring_no); + + int (*member_add) ( + void *transport_context, + const struct totem_ip_address *local, + const struct totem_ip_address *member, + int ring_no); + + int (*member_remove) ( + void *transport_context, + const struct totem_ip_address *member, + int ring_no); + + int (*member_set_active) ( + void *transport_context, + const struct totem_ip_address *member, + int active); + + int (*reconfigure) ( + void *net_context, + struct totem_config *totem_config); + + int (*crypto_reconfigure_phase) ( + void *net_context, + struct totem_config *totem_config, + cfg_message_crypto_reconfig_phase_t phase); + + void (*stats_clear) ( + void *net_context); +}; + +struct transport transport_entries[] = { + { + .name = "UDP/IP Multicast", + .initialize = totemudp_initialize, + .buffer_alloc = totemudp_buffer_alloc, + .buffer_release = totemudp_buffer_release, + .processor_count_set = totemudp_processor_count_set, + .token_send = totemudp_token_send, + .mcast_flush_send = totemudp_mcast_flush_send, + .mcast_noflush_send = totemudp_mcast_noflush_send, + .recv_flush = totemudp_recv_flush, + .send_flush = totemudp_send_flush, + .iface_set = totemudp_iface_set, + .iface_check = totemudp_iface_check, + .finalize = totemudp_finalize, + .net_mtu_adjust = totemudp_net_mtu_adjust, + .ifaces_get = totemudp_ifaces_get, + .nodestatus_get = totemudp_nodestatus_get, + .token_target_set = totemudp_token_target_set, + .crypto_set = totemudp_crypto_set, + .recv_mcast_empty = totemudp_recv_mcast_empty, + .member_add = totemudp_member_add, + .member_remove = totemudp_member_remove, + .reconfigure = totemudp_reconfigure, + .crypto_reconfigure_phase = NULL + }, + { + .name = "UDP/IP Unicast", + .initialize = totemudpu_initialize, + .buffer_alloc = totemudpu_buffer_alloc, + .buffer_release = totemudpu_buffer_release, + .processor_count_set = totemudpu_processor_count_set, + .token_send = totemudpu_token_send, + .mcast_flush_send = totemudpu_mcast_flush_send, + .mcast_noflush_send = totemudpu_mcast_noflush_send, + .recv_flush = totemudpu_recv_flush, + .send_flush = totemudpu_send_flush, + .iface_set = totemudpu_iface_set, + .iface_check = totemudpu_iface_check, + .finalize = totemudpu_finalize, + .net_mtu_adjust = totemudpu_net_mtu_adjust, + .ifaces_get = totemudpu_ifaces_get, + .nodestatus_get = totemudpu_nodestatus_get, + .token_target_set = totemudpu_token_target_set, + .crypto_set = totemudpu_crypto_set, + .recv_mcast_empty = totemudpu_recv_mcast_empty, + .member_add = totemudpu_member_add, + .member_remove = totemudpu_member_remove, + .reconfigure = totemudpu_reconfigure, + .crypto_reconfigure_phase = NULL + }, + { + .name = "Kronosnet", + .initialize = totemknet_initialize, + .buffer_alloc = totemknet_buffer_alloc, + .buffer_release = totemknet_buffer_release, + .processor_count_set = totemknet_processor_count_set, + .token_send = totemknet_token_send, + .mcast_flush_send = totemknet_mcast_flush_send, + .mcast_noflush_send = totemknet_mcast_noflush_send, + .recv_flush = totemknet_recv_flush, + .send_flush = totemknet_send_flush, + .iface_set = totemknet_iface_set, + .iface_check = totemknet_iface_check, + .finalize = totemknet_finalize, + .net_mtu_adjust = totemknet_net_mtu_adjust, + .ifaces_get = totemknet_ifaces_get, + .nodestatus_get = totemknet_nodestatus_get, + .token_target_set = totemknet_token_target_set, + .crypto_set = totemknet_crypto_set, + .recv_mcast_empty = totemknet_recv_mcast_empty, + .member_add = totemknet_member_add, + .member_remove = totemknet_member_remove, + .reconfigure = totemknet_reconfigure, + .crypto_reconfigure_phase = totemknet_crypto_reconfigure_phase, + .stats_clear = totemknet_stats_clear + } +}; + +struct totemnet_instance { + void *transport_context; + + struct transport *transport; + void (*totemnet_log_printf) ( + int level, + int subsys, + const char *function, + const char *file, + int line, + const char *format, + ...)__attribute__((format(printf, 6, 7))); + + int totemnet_subsys_id; +}; + +#define log_printf(level, format, args...) \ +do { \ + instance->totemnet_log_printf ( \ + level, \ + instance->totemnet_subsys_id, \ + __FUNCTION__, __FILE__, __LINE__, \ + (const char *)format, ##args); \ +} while (0); + +static void totemnet_instance_initialize ( + struct totemnet_instance *instance, + struct totem_config *config) +{ + int transport; + + instance->totemnet_log_printf = config->totem_logging_configuration.log_printf; + instance->totemnet_subsys_id = config->totem_logging_configuration.log_subsys_id; + + + transport = config->transport_number; + + log_printf (LOGSYS_LEVEL_NOTICE, + "Initializing transport (%s).", transport_entries[transport].name); + + instance->transport = &transport_entries[transport]; +} + +int totemnet_crypto_set ( + void *net_context, + const char *cipher_type, + const char *hash_type) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->crypto_set (instance->transport_context, + cipher_type, hash_type); + + return res; +} + +int totemnet_finalize ( + void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->finalize (instance->transport_context); + + return (res); +} + +int totemnet_initialize ( + qb_loop_t *loop_pt, + void **net_context, + struct totem_config *totem_config, + totemsrp_stats_t *stats, + void *context, + + int (*deliver_fn) ( + void *context, + const void *msg, + unsigned int msg_len, + const struct sockaddr_storage *system_from), + + int (*iface_change_fn) ( + void *context, + const struct totem_ip_address *iface_address, + unsigned int ring_no), + + void (*mtu_changed) ( + void *context, + int net_mtu), + + void (*target_set_completed) ( + void *context)) +{ + struct totemnet_instance *instance; + unsigned int res; + + instance = malloc (sizeof (struct totemnet_instance)); + if (instance == NULL) { + return (-1); + } + totemnet_instance_initialize (instance, totem_config); + + res = instance->transport->initialize (loop_pt, + &instance->transport_context, totem_config, stats, + context, deliver_fn, iface_change_fn, mtu_changed, target_set_completed); + + if (res == -1) { + goto error_destroy; + } + + *net_context = instance; + return (0); + +error_destroy: + free (instance); + return (-1); +} + +void *totemnet_buffer_alloc (void *net_context) +{ + struct totemnet_instance *instance = net_context; + assert (instance != NULL); + assert (instance->transport != NULL); + return instance->transport->buffer_alloc(); +} + +void totemnet_buffer_release (void *net_context, void *ptr) +{ + struct totemnet_instance *instance = net_context; + assert (instance != NULL); + assert (instance->transport != NULL); + instance->transport->buffer_release (ptr); +} + +int totemnet_processor_count_set ( + void *net_context, + int processor_count) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->processor_count_set (instance->transport_context, processor_count); + return (res); +} + +int totemnet_recv_flush (void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->recv_flush (instance->transport_context); + + return (res); +} + +int totemnet_send_flush (void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->send_flush (instance->transport_context); + + return (res); +} + +int totemnet_token_send ( + void *net_context, + const void *msg, + unsigned int msg_len) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->token_send (instance->transport_context, msg, msg_len); + + return (res); +} +int totemnet_mcast_flush_send ( + void *net_context, + const void *msg, + unsigned int msg_len) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->mcast_flush_send (instance->transport_context, msg, msg_len); + + return (res); +} + +int totemnet_mcast_noflush_send ( + void *net_context, + const void *msg, + unsigned int msg_len) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->mcast_noflush_send (instance->transport_context, msg, msg_len); + + return (res); +} + +extern int totemnet_iface_check (void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + res = instance->transport->iface_check (instance->transport_context); + + return (res); +} + +extern int totemnet_net_mtu_adjust (void *net_context, struct totem_config *totem_config) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res = 0; + + instance->transport->net_mtu_adjust (instance->transport_context, totem_config); + return (res); +} + +int totemnet_iface_set (void *net_context, + const struct totem_ip_address *interface_addr, + unsigned short ip_port, + unsigned int iface_no) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + int res; + + res = instance->transport->iface_set (instance->transport_context, interface_addr, ip_port, iface_no); + + return (res); +} + +extern int totemnet_nodestatus_get ( + void *net_context, + unsigned int nodeid, + struct totem_node_status *node_status) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res; + + res = instance->transport->nodestatus_get (instance->transport_context, nodeid, node_status); + + return (res); +} + +int totemnet_ifaces_get ( + void *net_context, + char ***status, + unsigned int *iface_count) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res; + + res = instance->transport->ifaces_get (instance->transport_context, status, iface_count); + + return (res); +} + +int totemnet_token_target_set ( + void *net_context, + unsigned int nodeid) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res; + + res = instance->transport->token_target_set (instance->transport_context, nodeid); + + return (res); +} + +extern int totemnet_recv_mcast_empty ( + void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res; + + res = instance->transport->recv_mcast_empty (instance->transport_context); + + return (res); +} + +extern int totemnet_member_add ( + void *net_context, + const struct totem_ip_address *local, + const struct totem_ip_address *member, + int ring_no) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res = 0; + + if (instance->transport->member_add) { + res = instance->transport->member_add ( + instance->transport_context, + local, + member, + ring_no); + } + + return (res); +} + +extern int totemnet_member_remove ( + void *net_context, + const struct totem_ip_address *member, + int ring_no) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res = 0; + + if (instance->transport->member_remove) { + res = instance->transport->member_remove ( + instance->transport_context, + member, + ring_no); + } + + return (res); +} + +int totemnet_member_set_active ( + void *net_context, + const struct totem_ip_address *member, + int active) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res = 0; + + if (instance->transport->member_set_active) { + res = instance->transport->member_set_active ( + instance->transport_context, + member, + active); + } + + return (res); +} + +int totemnet_reconfigure ( + void *net_context, + struct totem_config *totem_config) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res = 0; + + res = instance->transport->reconfigure ( + instance->transport_context, + totem_config); + + return (res); +} + +int totemnet_crypto_reconfigure_phase ( + void *net_context, + struct totem_config *totem_config, + cfg_message_crypto_reconfig_phase_t phase) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + unsigned int res = 0; + + if (instance->transport->crypto_reconfigure_phase) { + res = instance->transport->crypto_reconfigure_phase ( + instance->transport_context, + totem_config, phase); + } + return (res); +} + +void totemnet_stats_clear ( + void *net_context) +{ + struct totemnet_instance *instance = (struct totemnet_instance *)net_context; + + if (instance->transport->stats_clear) { + instance->transport->stats_clear ( + instance->transport_context); + } +} |