Просмотр исходного кода

defect 979
This enhancement adds support for IPV6 to the trunk of openais.


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@856 fd59a12c-fef9-0310-b244-a6a79926bd2f

Steven Dake 20 лет назад
Родитель
Сommit
e4dfef72d5
40 измененных файлов с 1475 добавлено и 760 удалено
  1. 9 6
      exec/Makefile
  2. 34 34
      exec/amf.c
  3. 74 74
      exec/ckpt.c
  4. 1 1
      exec/ckpt.h
  5. 44 31
      exec/clm.c
  6. 1 1
      exec/clm.h
  7. 20 14
      exec/evs.c
  8. 77 78
      exec/evt.c
  9. 4 4
      exec/handlers.h
  10. 2 0
      exec/lck.c
  11. 14 14
      exec/main.c
  12. 1 1
      exec/main.h
  13. 1 1
      exec/mainparse.h
  14. 7 7
      exec/sync.c
  15. 4 4
      exec/sync.h
  16. 8 5
      exec/totem.h
  17. 26 7
      exec/totemconfig.c
  18. 366 0
      exec/totemip.c
  19. 73 0
      exec/totemip.h
  20. 12 12
      exec/totemmrp.c
  21. 4 6
      exec/totemmrp.h
  22. 337 200
      exec/totemnet.c
  23. 3 3
      exec/totemnet.h
  24. 21 20
      exec/totempg.c
  25. 4 4
      exec/totempg.h
  26. 21 21
      exec/totemrrp.c
  27. 3 3
      exec/totemrrp.h
  28. 155 147
      exec/totemsrp.c
  29. 4 6
      exec/totemsrp.h
  30. 15 6
      include/evs.h
  31. 5 5
      include/ipc_evs.h
  32. 3 3
      include/ipc_evt.h
  33. 2 1
      include/ipc_gen.h
  34. 3 3
      lib/evs.c
  35. 25 4
      man/evs_initialize.3
  36. 3 2
      man/evs_membership_get.3
  37. 18 0
      man/openais.conf.5
  38. 29 11
      man/openais_overview.8
  39. 14 7
      test/evsbench.c
  40. 28 14
      test/testevs.c

+ 9 - 6
exec/Makefile

@@ -29,13 +29,13 @@
 # THE POSSIBILITY OF SUCH DAMAGE.
 
 # Production mode flags
-CFLAGS = -O3 -Wall -fomit-frame-pointer
-LDFLAGS = -lpthread
+#CFLAGS = -O3 -Wall -fomit-frame-pointer
+#LDFLAGS = -lpthread
 
 # Debug mode flags
-#CFLAGS = -g -Wall
+CFLAGS = -g -Wall
 ##-DDEBUG
-#LDFLAGS = -g -lpthread
+LDFLAGS = -g -lpthread
 
 # Profile mode flags
 #CFLAGS = -O3 -pg
@@ -45,8 +45,8 @@ LDFLAGS = -lpthread
 #CFLAGS = -ftest-coverage -fprofile-arcs
 #LDFLAGS = -g
 
-TOTEM_SRC = aispoll.c totemnet.c totemrrp.c totemsrp.c totemmrp.c totempg.c totemconfig.c tlist.c hdb.c crypto.c wthread.c
-TOTEM_OBJS = aispoll.o totemnet.o totemrrp.o totemsrp.o totemmrp.o totempg.o totemconfig.o tlist.o hdb.o crypto.o wthread.o
+TOTEM_SRC = aispoll.c totemip.c totemnet.c totemrrp.c totemsrp.c totemmrp.c totempg.c totemconfig.c tlist.c hdb.c crypto.c wthread.c
+TOTEM_OBJS = aispoll.o totemip.o totemnet.o totemrrp.o totemsrp.o totemmrp.o totempg.o totemconfig.o tlist.o hdb.o crypto.o wthread.o
 
 EXEC_SRC = main.c clm.c amf.c ckpt.c evt.c lck.c evs.c mainparse.c print.c mempool.c \
 		util.c sync.c
@@ -92,6 +92,9 @@ totemsrp.o: totemsrp.c
 totemrrp.o: totemrrp.c
 	$(CC) $(CFLAGS) -fPIC -c -o $@ $(*F).c
 
+totemip.o: totemip.c
+	$(CC) $(CFLAGS) -fPIC -c -o $@ $(*F).c
+
 totemnet.o: totemnet.c
 	$(CC) $(CFLAGS) -fPIC -c -o $@ $(*F).c
 

+ 34 - 34
exec/amf.c

@@ -237,9 +237,9 @@ static void amf_confchg_njoin (
 
 static int amf_confchg_fn (
 	enum totem_configuration_type configuration_type,
-    struct in_addr *member_list, int member_list_entries,
-    struct in_addr *left_list, int left_list_entries,
-    struct in_addr *joined_list, int joined_list_entries,
+    struct totem_ip_address *member_list, int member_list_entries,
+    struct totem_ip_address *left_list, int left_list_entries,
+    struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id);
 
 /***
@@ -252,19 +252,19 @@ static int amf_exec_init_fn (struct openais_config *);
 
 static int amf_init_two_fn (struct conn_info *conn_info);
 
-static void amf_synchronize (void *message, struct in_addr source_addr);
+static void amf_synchronize (void *message, struct totem_ip_address *source_addr);
 
-static int message_handler_req_exec_amf_componentregister (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_componentregister (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_amf_componentunregister (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_componentunregister (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_amf_errorreport (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_errorreport (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_amf_errorcancelall (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_errorcancelall (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_amf_readinessstateset (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_readinessstateset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_amf_hastateset (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_amf_hastateset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
 static int message_handler_req_amf_componentregister (struct conn_info *conn_info, void *message);
 
@@ -361,7 +361,7 @@ struct libais_handler amf_libais_handlers[] =
 	}
 };
 
-int (*amf_aisexec_handler_fns[]) (void *, struct in_addr source_addr, int endian_conversion_required) = {
+int (*amf_aisexec_handler_fns[]) (void *, struct totem_ip_address *source_addr, int endian_conversion_required) = {
 	message_handler_req_exec_amf_componentregister,
 	message_handler_req_exec_amf_componentunregister,
 	message_handler_req_exec_amf_errorreport,
@@ -521,7 +521,7 @@ static void component_unregister (
 	req_exec_amf_componentunregister.header.id = MESSAGE_REQ_EXEC_AMF_COMPONENTUNREGISTER;
 
 	req_exec_amf_componentunregister.source.conn_info = 0;
-	req_exec_amf_componentunregister.source.in_addr.s_addr = 0;
+	req_exec_amf_componentunregister.source.addr.family = 0;
 
 	memset (&req_exec_amf_componentunregister.req_lib_amf_componentunregister,
 		0, sizeof (struct req_lib_amf_componentunregister));
@@ -554,7 +554,7 @@ static void component_register (
 	req_exec_amf_componentregister.header.id = MESSAGE_REQ_EXEC_AMF_COMPONENTREGISTER;
 
 	req_exec_amf_componentregister.source.conn_info = 0;
-	req_exec_amf_componentregister.source.in_addr.s_addr = 0;
+	req_exec_amf_componentregister.source.addr.family = 0;
 	req_exec_amf_componentregister.currentReadinessState = component->currentReadinessState;
 	req_exec_amf_componentregister.newReadinessState = component->newReadinessState;
 	req_exec_amf_componentregister.currentHAState = component->currentHAState;
@@ -1454,7 +1454,7 @@ void error_report (
 	req_exec_amf_errorreport.header.id = MESSAGE_REQ_EXEC_AMF_ERRORREPORT;
 
 	req_exec_amf_errorreport.source.conn_info = 0;
-	req_exec_amf_errorreport.source.in_addr.s_addr = 0;
+	req_exec_amf_errorreport.source.addr.family = 0;
 	memcpy (&req_exec_amf_errorreport.req_lib_amf_errorreport.erroneousComponent,
 		&component->name,
 		sizeof (SaNameT));
@@ -1870,7 +1870,7 @@ static int amf_exec_init_fn (struct openais_config *openais_config)
 
 void amf_confchg_njoin (struct saAmfComponent *component ,void *data)
 {
-	if (component->source_addr.s_addr != this_ip->sin_addr.s_addr) {
+	if (!totemip_equal(&component->source_addr, this_ip)) {
 		return;
 	}
 
@@ -1880,13 +1880,13 @@ void amf_confchg_njoin (struct saAmfComponent *component ,void *data)
 
 void amf_confchg_nleave (struct saAmfComponent *component ,void *data)
 {
-	struct in_addr *source_addr = (struct in_addr *)data;
+	struct totem_ip_address *source_addr = (struct totem_ip_address *)data;
 	struct saAmfUnit *unit;
 	struct list_head *list;
 	struct saAmfComponent *leave_component = NULL;
 	enum amfDisabledUnlockedState disablestate = AMF_DISABLED_UNLOCKED_OUT_OF_SERVICE_COMPLETED;
 
-	if (component->source_addr.s_addr != source_addr->s_addr) {
+	if (!totemip_equal(&component->source_addr, source_addr)) {
 		return;
 	}
 
@@ -1904,7 +1904,7 @@ void amf_confchg_nleave (struct saAmfComponent *component ,void *data)
 		component = list_entry (list,
 			struct saAmfComponent, saAmfComponentList);
 
-		if (component->source_addr.s_addr != source_addr->s_addr) {
+		if (!totemip_equal(&component->source_addr, source_addr)) {
 			disablestate = AMF_DISABLED_UNLOCKED_FAILED;
 			continue;
 	  	}
@@ -1917,7 +1917,7 @@ void amf_confchg_nleave (struct saAmfComponent *component ,void *data)
 		component->currentReadinessState = SA_AMF_OUT_OF_SERVICE;
 		component->newHAState = SA_AMF_QUIESCED;
 		component->currentHAState = SA_AMF_QUIESCED;
-		component->source_addr.s_addr = 0;
+		component->source_addr.family = 0;
 		leave_component = component;
 	}
 
@@ -1936,9 +1936,9 @@ void amf_confchg_nleave (struct saAmfComponent *component ,void *data)
 
 static int amf_confchg_fn (
 	enum totem_configuration_type configuration_type,
-    struct in_addr *member_list, int member_list_entries,
-    struct in_addr *left_list, int left_list_entries,
-    struct in_addr *joined_list, int joined_list_entries,
+    struct totem_ip_address *member_list, int member_list_entries,
+    struct totem_ip_address *left_list, int left_list_entries,
+    struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 	int i;
@@ -1997,7 +1997,7 @@ int amf_exit_fn (struct conn_info *conn_info)
 	return (0);
 }
 
-static int message_handler_req_exec_amf_componentregister (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_componentregister (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_componentregister *req_exec_amf_componentregister = (struct req_exec_amf_componentregister *)message;
 	struct res_lib_amf_componentregister res_lib_amf_componentregister;
@@ -2018,7 +2018,7 @@ static int message_handler_req_exec_amf_componentregister (void *message, struct
 	/*
 	 * If a node is joining menber ship ,Component States Synchronize
 	 */
-	if (req_exec_amf_componentregister->source.in_addr.s_addr == 0) {
+	if (req_exec_amf_componentregister->source.addr.family == 0) {
 		amf_synchronize (message, source_addr);
 		return (0);
 	}
@@ -2057,7 +2057,7 @@ static int message_handler_req_exec_amf_componentregister (void *message, struct
 		component->local = 0;
 		component->registered = 1;
 		component->conn_info = req_exec_amf_componentregister->source.conn_info;
-		component->source_addr = source_addr;
+		totemip_copy(&component->source_addr, source_addr);
 		component->currentReadinessState = SA_AMF_OUT_OF_SERVICE;
 		component->newReadinessState = SA_AMF_OUT_OF_SERVICE;
 		component->currentHAState = 0;
@@ -2104,7 +2104,7 @@ static int message_handler_req_exec_amf_componentregister (void *message, struct
 	return (0);
 }
 
-static void amf_synchronize (void *message, struct in_addr source_addr)
+static void amf_synchronize (void *message, struct totem_ip_address *source_addr)
 {
 	struct req_exec_amf_componentregister *req_exec_amf_componentregister = (struct req_exec_amf_componentregister *)message;
 	struct saAmfComponent *component;
@@ -2118,7 +2118,7 @@ static void amf_synchronize (void *message, struct in_addr source_addr)
 	amfProxyComponent = findComponent (&req_exec_amf_componentregister->req_lib_amf_componentregister.proxyCompName);
 
 	/* If this processor is component owner */
-	if (component->source_addr.s_addr == this_ip->sin_addr.s_addr) {
+	if (totemip_equal(&component->source_addr, this_ip)) {
 
 		/* No Operation */
 		return;
@@ -2135,7 +2135,7 @@ static void amf_synchronize (void *message, struct in_addr source_addr)
 	component->local = 0;
 	component->registered = 1;
 	component->conn_info = req_exec_amf_componentregister->source.conn_info;
-	component->source_addr = source_addr;
+	totemip_copy(&component->source_addr, source_addr);
 	component->currentReadinessState = SA_AMF_OUT_OF_SERVICE;
 	component->newReadinessState = SA_AMF_OUT_OF_SERVICE;
 	component->currentHAState = SA_AMF_QUIESCED;
@@ -2160,7 +2160,7 @@ static void amf_synchronize (void *message, struct in_addr source_addr)
 	return;
 }
 
-static int message_handler_req_exec_amf_componentunregister (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_componentunregister (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_componentunregister *req_exec_amf_componentunregister = (struct req_exec_amf_componentunregister *)message;
 	struct res_lib_amf_componentunregister res_lib_amf_componentunregister;
@@ -2228,7 +2228,7 @@ static int message_handler_req_exec_amf_componentunregister (void *message, stru
 	return (0);
 }
 
-static int message_handler_req_exec_amf_errorreport (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_errorreport (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_errorreport *req_exec_amf_errorreport = (struct req_exec_amf_errorreport *)message;
 	struct res_lib_amf_errorreport res_lib_amf_errorreport;
@@ -2269,7 +2269,7 @@ static int message_handler_req_exec_amf_errorreport (void *message, struct in_ad
 	return (0);
 }
 
-static int message_handler_req_exec_amf_errorcancelall (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_errorcancelall (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_errorcancelall *req_exec_amf_errorcancelall = (struct req_exec_amf_errorcancelall *)message;
 	struct res_lib_amf_errorcancelall res_lib_amf_errorcancelall;
@@ -2318,7 +2318,7 @@ static int message_handler_req_exec_amf_errorcancelall (void *message, struct in
  * node.  That cluster node API has verified the readiness state, so its time to let
  * the rest of the cluster nodes know about the readiness state change.
  */
-static int message_handler_req_exec_amf_readinessstateset (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_readinessstateset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_readinessstateset *req_exec_amf_readinessstateset = (struct req_exec_amf_readinessstateset *)message;
 	struct saAmfComponent *component;
@@ -2343,7 +2343,7 @@ static int message_handler_req_exec_amf_readinessstateset (void *message, struct
  * node.  That cluster node API has verified the ha state, so its time to let
  * the rest of the cluster nodes know about the HA state change.
  */
-static int message_handler_req_exec_amf_hastateset (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_amf_hastateset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_amf_hastateset *req_exec_amf_hastateset = (struct req_exec_amf_hastateset *)message;
 	struct saAmfComponent *component;
@@ -2849,7 +2849,7 @@ static void amf_dump_comp (struct saAmfComponent *component ,void *data)
 	log_printf (level, "----------------\n" );
 	log_printf (level, "registered            = %d\n" ,component->registered);
 	log_printf (level, "local                 = %d\n" ,component->local );
-	log_printf (level, "source_addr           = %s\n" ,inet_ntoa (component->source_addr));
+	log_printf (level, "source_addr           = %s\n" ,totemip_print (&component->source_addr));
 	memset (name, 0 , sizeof(name));
 	memcpy (name, component->name.value, component->name.length);
 	log_printf (level, "name                  = %s\n" ,name );

+ 74 - 74
exec/ckpt.c

@@ -91,31 +91,31 @@ static int ckpt_exit_fn (struct conn_info *conn_info);
 
 static int ckpt_init_two_fn (struct conn_info *conn_info);
 
-static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_synchronize_state (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_synchronize_state (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_synchronize_section (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_synchronize_section (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_checkpointclose (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_checkpointclose (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
-static int message_handler_req_exec_ckpt_sectionread (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_ckpt_sectionread (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
 static int message_handler_req_lib_ckpt_checkpointopen (struct conn_info *conn_info, void *message);
 
@@ -157,9 +157,9 @@ static void ckpt_recovery_initialize (void);
 static int  ckpt_recovery_process (void);
 static void ckpt_recovery_finalize();
 static void ckpt_recovery_abort(void);
-static void ckpt_recovery_process_members_exit(struct in_addr *left_list, 
+static void ckpt_recovery_process_members_exit(struct totem_ip_address *left_list, 
 						int left_list_entries); 
-static void ckpt_replace_localhost_ip (struct in_addr *joined_list);
+static void ckpt_replace_localhost_ip (struct totem_ip_address *joined_list);
 
 void checkpoint_release (struct saCkptCheckpoint *checkpoint);
 void timer_function_retention (void *data);
@@ -189,9 +189,9 @@ static struct memb_ring_id saved_ring_id;
 
 static int ckpt_confchg_fn(
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id);
 
 /*
@@ -310,7 +310,7 @@ struct libais_handler ckpt_libais_handlers[] =
 };
 
 
-static int (*ckpt_aisexec_handler_fns[]) (void *msg, struct in_addr source_addr, int endian_conversion_required) = {
+static int (*ckpt_aisexec_handler_fns[]) (void *msg, struct totem_ip_address *source_addr, int endian_conversion_required) = {
 	message_handler_req_exec_ckpt_checkpointopen,
 	message_handler_req_exec_ckpt_checkpointclose,
 	message_handler_req_exec_ckpt_checkpointunlink,
@@ -427,7 +427,7 @@ struct req_exec_ckpt_synchronize_state {
 	SaNameT checkpointName;
 	SaCkptCheckpointCreationAttributesT checkpointCreationAttributes;
 	SaCkptSectionDescriptorT sectionDescriptor;	
-	struct in_addr source_addr;
+	struct totem_ip_address *source_addr;
 	struct ckpt_refcnt ckpt_refcount[PROCESSOR_COUNT_MAX];
 };
 
@@ -443,25 +443,25 @@ struct req_exec_ckpt_synchronize_section {
 /* 
  * Implementation
  */
-static int processor_index_set(struct in_addr *proc_addr, 
+static int processor_index_set(struct totem_ip_address *proc_addr, 
 								struct ckpt_refcnt *ckpt_refcount) 
 {
 	int i;
 	for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-		if (ckpt_refcount[i].addr.s_addr == 0) {
+		if (ckpt_refcount[i].addr.family == 0) {
 			/*
 			 * If the source addresses do not match and this element
 			 * has no stored value then store the new value and 
 			 * return the Index.
 		 	 */		
-			memcpy(&ckpt_refcount[i].addr, proc_addr, sizeof(struct in_addr));			
+			totemip_copy(&ckpt_refcount[i].addr, proc_addr);
 			return i;
 		}
 		/*
 		* If the source addresses match then this processor index
 		* has already been set
 		*/
-		else if (ckpt_refcount[i].addr.s_addr == proc_addr->s_addr) {
+		else if (totemip_equal(&ckpt_refcount[i].addr, proc_addr)) {
 			return -1;
 		}
 
@@ -471,13 +471,13 @@ static int processor_index_set(struct in_addr *proc_addr,
 	 * to store the new Processor.	
 	 */
 	for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-		if (ckpt_refcount[i].addr.s_addr == 0) {
+		if (ckpt_refcount[i].addr.family == 0) {
 			log_printf (LOG_LEVEL_ERROR,"Processor Set: Index %d has proc 0 and count 0\n", i);
 		}
 		else {
 			log_printf (LOG_LEVEL_ERROR,"Processor Set: Index %d has proc %s and count %d\n",
                                 i,
-                                inet_ntoa(ckpt_refcount[i].addr),
+                                totemip_print(&ckpt_refcount[i].addr),
                                 ckpt_refcount[i].count);
                 }
         }
@@ -485,21 +485,21 @@ static int processor_index_set(struct in_addr *proc_addr,
 	return -1;
 }
 
-static int processor_add (struct in_addr *proc_addr, int count, struct ckpt_refcnt *ckpt_refcount) 
+static int processor_add (struct totem_ip_address *proc_addr, int count, struct ckpt_refcnt *ckpt_refcount) 
 {
 	int i;
         for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-                if (ckpt_refcount[i].addr.s_addr == 0) {
+                if (ckpt_refcount[i].addr.family == 0) {
 			log_printf (LOG_LEVEL_DEBUG,"processor_add found empty slot to insert new item\n");
-                        memcpy(&ckpt_refcount[i].addr, proc_addr, sizeof(struct in_addr));
+                        totemip_copy(&ckpt_refcount[i].addr, proc_addr);
 			ckpt_refcount[i].count = count;
                         return i;
                 }
 		/*Dont know how we missed this in the processor find but update this*/
-		else if (ckpt_refcount[i].addr.s_addr == proc_addr->s_addr) {
+		else if (totemip_equal(&ckpt_refcount[i].addr, proc_addr)) {
 			ckpt_refcount[i].count += count;
 			log_printf (LOG_LEVEL_DEBUG,"processor_add for existent proc. ip %s, New count = %d\n",
-				inet_ntoa(ckpt_refcount[i].addr),
+				totemip_print(&ckpt_refcount[i].addr),
 				ckpt_refcount[i].count);
 
 			return i;
@@ -511,13 +511,13 @@ static int processor_add (struct in_addr *proc_addr, int count, struct ckpt_refc
          */
 	log_printf (LOG_LEVEL_ERROR,"Processor Add Failed. Dumping Refcount Array\n");
 	for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-		if (ckpt_refcount[i].addr.s_addr == 0) {
+		if (ckpt_refcount[i].addr.family == 0) {
 			log_printf (LOG_LEVEL_ERROR,"Processor Add: Index %d has proc 0 and count 0\n", i);
 		}
 		else {
 			log_printf (LOG_LEVEL_ERROR,"Processor Add: Index %d has proc %s and count %d\n",
 				i,
-				inet_ntoa(ckpt_refcount[i].addr),
+				totemip_print(&ckpt_refcount[i].addr),
 				ckpt_refcount[i].count);
 		}
 	}
@@ -525,7 +525,7 @@ static int processor_add (struct in_addr *proc_addr, int count, struct ckpt_refc
 
 }
 
-static int processor_index_find(struct in_addr *proc_addr,
+static int processor_index_find(struct totem_ip_address *proc_addr,
 								struct ckpt_refcnt *ckpt_refcount) 
 { 
 	int i;
@@ -534,7 +534,7 @@ static int processor_index_find(struct in_addr *proc_addr,
 		 * If the source addresses match then return the index
 		 */
 		
-		if (ckpt_refcount[i].addr.s_addr == proc_addr->s_addr) {
+		if (totemip_equal(&ckpt_refcount[i].addr, proc_addr)) {
 			return i;
 		}				
 	}
@@ -564,13 +564,13 @@ static void merge_ckpt_refcounts(struct ckpt_refcnt *local, struct ckpt_refcnt *
 	int index,i;	
 
 	for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-		if (local[i].addr.s_addr == 0) {
+		if (local[i].addr.family == 0) {
 			continue;
 		}
 		index  = processor_index_find (&local[i].addr, network);
 		if (index == -1) { /*Could Not Find the Local Entry in the remote.Add to it*/
 			log_printf (LOG_LEVEL_DEBUG,"calling processor_add for ip %s, count %d\n",
-				inet_ntoa(local[i].addr),
+				totemip_print(&local[i].addr),
 				local[i].count);
 			index = processor_add (&local[i].addr, local[i].count, network);
 			if (index == -1) {
@@ -589,7 +589,7 @@ static void merge_ckpt_refcounts(struct ckpt_refcnt *local, struct ckpt_refcnt *
 				/*Found a match for this proc in the Network choose the larger of the 2.*/
 				network[index].count += local[i].count; 
 				log_printf (LOG_LEVEL_DEBUG,"setting count for %s = %d\n",
-					inet_ntoa(network[index].addr),
+					totemip_print(&network[index].addr),
 					network[index].count);
 			}
 		}
@@ -720,7 +720,7 @@ static int ckpt_recovery_process (void)
 					memcpy(&request_exec_sync_state.sectionDescriptor,
 							&ckptCheckpointSection->sectionDescriptor,
 							sizeof(SaCkptSectionDescriptorT));						
-					memcpy(&request_exec_sync_state.source_addr, &this_ip->sin_addr, sizeof(struct in_addr));
+					memcpy(&request_exec_sync_state.source_addr, &this_ip, sizeof(struct totem_ip_address));
 				 			
 					memcpy(request_exec_sync_state.ckpt_refcount,
 							checkpoint->ckpt_refcount,
@@ -729,14 +729,14 @@ static int ckpt_recovery_process (void)
 
 					log_printf (LOG_LEVEL_DEBUG, "CKPT: New Sync State Message Values\n");
 					for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-						if (request_exec_sync_state.ckpt_refcount[i].addr.s_addr == 0) {
+						if (request_exec_sync_state.ckpt_refcount[i].addr.family == 0) {
 							log_printf (LOG_LEVEL_DEBUG,"Index %d has proc 0 and count %d\n", i,
 								request_exec_sync_state.ckpt_refcount[i].count);
 						}
 						else {
 							log_printf (LOG_LEVEL_DEBUG,"Index %d has proc %s and count %d\n",
 							i,
-							inet_ntoa(request_exec_sync_state.ckpt_refcount[i].addr),
+							totemip_print(&request_exec_sync_state.ckpt_refcount[i].addr),
 							request_exec_sync_state.ckpt_refcount[i].count);
 						}
 					}
@@ -966,15 +966,15 @@ static void ckpt_recovery_abort (void)
 	return;
 }
 
-static void ckpt_replace_localhost_ip (struct in_addr *joined_list) {
+static void ckpt_replace_localhost_ip (struct totem_ip_address *joined_list) {
 	struct list_head *checkpoint_list;
         struct saCkptCheckpoint *checkpoint;
-        struct in_addr local_ip;
+        struct totem_ip_address local_ip;
         int index;
 
 	assert(joined_list);
 
-	local_ip.s_addr = inet_addr("127.0.0.1");
+	totemip_localhost(AF_INET, &local_ip);
 
 	for (checkpoint_list = checkpoint_list_head.next;
 		checkpoint_list != &checkpoint_list_head;
@@ -988,31 +988,31 @@ static void ckpt_replace_localhost_ip (struct in_addr *joined_list) {
 		}		
 		memcpy(&checkpoint->ckpt_refcount[index].addr, joined_list, sizeof(struct in_addr));
 		log_printf (LOG_LEVEL_DEBUG, "Transitioning From Local Host replacing 127.0.0.1 with %s ...\n",
-			inet_ntoa(*joined_list));
+			totemip_print(joined_list));
 
 	}
 	process_localhost_transition = 0;
 }
 
 
-static void ckpt_recovery_process_members_exit(struct in_addr *left_list, 
+static void ckpt_recovery_process_members_exit(struct totem_ip_address *left_list, 
 						int left_list_entries)
 {
 	struct list_head *checkpoint_list;
 	struct saCkptCheckpoint *checkpoint;
-	struct in_addr *member;
-	struct in_addr local_ip;
+	struct totem_ip_address *member;
+	struct totem_ip_address local_ip;
 	int index;
 	int i;
 
-	local_ip.s_addr = inet_addr("127.0.0.1");
+	totemip_localhost(AF_INET, &local_ip);
 	
 	if (left_list_entries == 0) {
 		return;
 	}
 
 	if ((left_list_entries == 1) && 
-		(left_list->s_addr == local_ip.s_addr)) {
+	    (totemip_equal(left_list, &local_ip))) {
 		process_localhost_transition = 1;
 		return; 
 	}
@@ -1104,9 +1104,9 @@ void clean_checkpoint_list(struct list_head *head)
 
 static int ckpt_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id) 
 {
 
@@ -1297,7 +1297,7 @@ static int ckpt_exec_init_fn (struct openais_config *openais_config)
 	 *  Initialize the saved ring ID.
 	 */
 	saved_ring_id.seq = 0;
-	saved_ring_id.rep.s_addr = this_ip->sin_addr.s_addr;		
+	totemip_copy(&saved_ring_id.rep, this_ip);
 	
 #ifdef TODO
 	int res;
@@ -1348,7 +1348,7 @@ static int ckpt_exit_fn (struct conn_info *conn_info)
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_ckpt_checkpointopen *req_exec_ckpt_checkpointopen = (struct req_exec_ckpt_checkpointopen *)message;
 	struct req_lib_ckpt_checkpointopen *req_lib_ckpt_checkpointopen = (struct req_lib_ckpt_checkpointopen *)&req_exec_ckpt_checkpointopen->req_lib_ckpt_checkpointopen;
@@ -1468,12 +1468,12 @@ static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct i
 	 * 
 	 */
 	 
-	 proc_index = processor_index_find(&source_addr,ckptCheckpoint->ckpt_refcount);
+	 proc_index = processor_index_find(source_addr,ckptCheckpoint->ckpt_refcount);
 	 if (proc_index == -1) {/* Could not find, lets set the processor to an index.*/
-	 	proc_index = processor_index_set(&source_addr,ckptCheckpoint->ckpt_refcount);
+	 	proc_index = processor_index_set(source_addr,ckptCheckpoint->ckpt_refcount);
 	 }
 	 if (proc_index != -1 ) {	 
-	 	ckptCheckpoint->ckpt_refcount[proc_index].addr = source_addr;
+		 totemip_copy(&ckptCheckpoint->ckpt_refcount[proc_index].addr, source_addr);
 	 	ckptCheckpoint->ckpt_refcount[proc_index].count++;
 	 }
 	 else {
@@ -1552,14 +1552,14 @@ static int recovery_checkpoint_open(SaNameT *checkpointName,
 	log_printf (LOG_LEVEL_DEBUG, "CKPT: recovery_checkpoint_open %s\n", &checkpointName->value);
 	log_printf (LOG_LEVEL_DEBUG, "CKPT: recovery_checkpoint_open refcount Values\n");
 	for (i = 0; i < PROCESSOR_COUNT_MAX; i ++) {
-        	if (ref_cnt[i].addr.s_addr == 0) {
+        	if (ref_cnt[i].addr.family == 0) {
 			log_printf (LOG_LEVEL_DEBUG,"Index %d has proc 0 and count %d\n", i,
 				ref_cnt[i].count);
 		}
 		else {
 			log_printf (LOG_LEVEL_DEBUG,"Index %d has proc %s and count %d\n",
 				i,
-				inet_ntoa(ref_cnt[i].addr),
+				totemip_print(&ref_cnt[i].addr),
 				ref_cnt[i].count);
 		}
 	}
@@ -1673,7 +1673,7 @@ error_exit:
 	return (error);
 }
 
-static int message_handler_req_exec_ckpt_synchronize_state (void *message, struct in_addr source_addr, int endian_conversion_required) 
+static int message_handler_req_exec_ckpt_synchronize_state (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) 
 {
 	int retcode;
 	struct req_exec_ckpt_synchronize_state *req_exec_ckpt_sync_state 
@@ -1707,7 +1707,7 @@ static int message_handler_req_exec_ckpt_synchronize_state (void *message, struc
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_synchronize_section (void *message, struct in_addr source_addr, int endian_conversion_required) 
+static int message_handler_req_exec_ckpt_synchronize_section (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) 
 {
 	int retcode;
 	struct req_exec_ckpt_synchronize_section *req_exec_ckpt_sync_section 
@@ -1823,7 +1823,7 @@ void timer_function_retention (void *data)
 	assert (totempg_mcast (&iovec, 1, TOTEMPG_AGREED) == 0);
 }
 
-extern int message_handler_req_exec_ckpt_checkpointclose (void *message, struct in_addr source_addr, int endian_conversion_required)
+extern int message_handler_req_exec_ckpt_checkpointclose (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_ckpt_checkpointclose *req_exec_ckpt_checkpointclose = (struct req_exec_ckpt_checkpointclose *)message;
 	struct res_lib_ckpt_checkpointclose res_lib_ckpt_checkpointclose;
@@ -1845,7 +1845,7 @@ extern int message_handler_req_exec_ckpt_checkpointclose (void *message, struct
 	 * sent out later as a part of the sync process.	 
 	 */
 	
-	proc_index = processor_index_find(&source_addr, checkpoint->ckpt_refcount);
+	proc_index = processor_index_find(source_addr, checkpoint->ckpt_refcount);
 	if (proc_index != -1 ) {	 		
 	 	checkpoint->ckpt_refcount[proc_index].count--;
 	}
@@ -1887,7 +1887,7 @@ error_exit:
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_ckpt_checkpointunlink *req_exec_ckpt_checkpointunlink = (struct req_exec_ckpt_checkpointunlink *)message;
 
@@ -1932,7 +1932,7 @@ error_exit:
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_ckpt_checkpointretentiondurationset *req_exec_ckpt_checkpointretentiondurationset = (struct req_exec_ckpt_checkpointretentiondurationset *)message;
 	struct res_lib_ckpt_checkpointretentiondurationset res_lib_ckpt_checkpointretentiondurationset;
@@ -1975,7 +1975,7 @@ static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *m
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_ckpt_checkpointretentiondurationexpire *req_exec_ckpt_checkpointretentiondurationexpire = (struct req_exec_ckpt_checkpointretentiondurationexpire *)message;
 	struct req_exec_ckpt_checkpointunlink req_exec_ckpt_checkpointunlink;
@@ -1992,7 +1992,7 @@ static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void
 		req_exec_ckpt_checkpointunlink.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTUNLINK;
 
 		req_exec_ckpt_checkpointunlink.source.conn_info = 0;
-		req_exec_ckpt_checkpointunlink.source.in_addr.s_addr = 0;
+		req_exec_ckpt_checkpointunlink.source.addr.family = 0;
 
 		memcpy (&req_exec_ckpt_checkpointunlink.req_lib_ckpt_checkpointunlink.checkpointName,
 			&req_exec_ckpt_checkpointretentiondurationexpire->checkpointName,
@@ -2123,7 +2123,7 @@ error_exit:
 
 }
 
-static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectioncreate *req_exec_ckpt_sectioncreate = (struct req_exec_ckpt_sectioncreate *)message;
 	struct req_lib_ckpt_sectioncreate *req_lib_ckpt_sectioncreate = (struct req_lib_ckpt_sectioncreate *)&req_exec_ckpt_sectioncreate->req_lib_ckpt_sectioncreate;
 	struct res_lib_ckpt_sectioncreate res_lib_ckpt_sectioncreate;
@@ -2262,7 +2262,7 @@ error_exit:
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectiondelete *req_exec_ckpt_sectiondelete = (struct req_exec_ckpt_sectiondelete *)message;
 	struct req_lib_ckpt_sectiondelete *req_lib_ckpt_sectiondelete = (struct req_lib_ckpt_sectiondelete *)&req_exec_ckpt_sectiondelete->req_lib_ckpt_sectiondelete;
 	struct res_lib_ckpt_sectiondelete res_lib_ckpt_sectiondelete;
@@ -2325,7 +2325,7 @@ error_exit:
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectionexpirationtimeset *req_exec_ckpt_sectionexpirationtimeset = (struct req_exec_ckpt_sectionexpirationtimeset *)message;
 	struct req_lib_ckpt_sectionexpirationtimeset *req_lib_ckpt_sectionexpirationtimeset = (struct req_lib_ckpt_sectionexpirationtimeset *)&req_exec_ckpt_sectionexpirationtimeset->req_lib_ckpt_sectionexpirationtimeset;
 	struct res_lib_ckpt_sectionexpirationtimeset res_lib_ckpt_sectionexpirationtimeset;
@@ -2458,7 +2458,7 @@ error_exit:
 }
 
 
-static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectionwrite *req_exec_ckpt_sectionwrite = (struct req_exec_ckpt_sectionwrite *)message;
 	struct req_lib_ckpt_sectionwrite *req_lib_ckpt_sectionwrite = (struct req_lib_ckpt_sectionwrite *)&req_exec_ckpt_sectionwrite->req_lib_ckpt_sectionwrite;
 	struct res_lib_ckpt_sectionwrite res_lib_ckpt_sectionwrite;
@@ -2555,7 +2555,7 @@ error_exit:
 	return (0);
 }
 
-static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectionoverwrite *req_exec_ckpt_sectionoverwrite = (struct req_exec_ckpt_sectionoverwrite *)message;
 	struct req_lib_ckpt_sectionoverwrite *req_lib_ckpt_sectionoverwrite = (struct req_lib_ckpt_sectionoverwrite *)&req_exec_ckpt_sectionoverwrite->req_lib_ckpt_sectionoverwrite;
 	struct res_lib_ckpt_sectionoverwrite res_lib_ckpt_sectionoverwrite;
@@ -2631,7 +2631,7 @@ error_exit:
 	}
 	return (0);
 }
-static int message_handler_req_exec_ckpt_sectionread (void *message, struct in_addr source_addr, int endian_conversion_required) {
+static int message_handler_req_exec_ckpt_sectionread (void *message, struct totem_ip_address *source_addr, int endian_conversion_required) {
 	struct req_exec_ckpt_sectionread *req_exec_ckpt_sectionread = (struct req_exec_ckpt_sectionread *)message;
 	struct req_lib_ckpt_sectionread *req_lib_ckpt_sectionread = (struct req_lib_ckpt_sectionread *)&req_exec_ckpt_sectionread->req_lib_ckpt_sectionread;
 	struct res_lib_ckpt_sectionread res_lib_ckpt_sectionread;

+ 1 - 1
exec/ckpt.h

@@ -41,7 +41,7 @@
 
 struct ckpt_refcnt {
 	int count;
-	struct in_addr addr;
+	struct totem_ip_address addr;
 };
 
 struct saCkptCheckpointSection {

+ 44 - 31
exec/clm.c

@@ -81,16 +81,16 @@ static unsigned long long view_initial = 0;
 
 static DECLARE_LIST_INIT (library_notification_send_listhead);
 
-SaClmClusterNodeT *clm_get_by_nodeid (struct in_addr node_id)
+SaClmClusterNodeT *clm_get_by_nodeid (unsigned int node_id)
 {
 	SaClmClusterNodeT *ret = NULL;
 	int i;
 
-	if (node_id.s_addr == SA_CLM_LOCAL_NODE_ID) {
+	if (node_id == SA_CLM_LOCAL_NODE_ID) {
 		return (&clusterNodes[0]);
 	}
 	for (i = 0; i < clusterNodeEntries; i++) {
-		if (clusterNodes[i].nodeId == node_id.s_addr) {
+		if (clusterNodes[i].nodeId == node_id) {
 			ret = &clusterNodes[i];
 			break;
 		}
@@ -103,9 +103,9 @@ SaClmClusterNodeT *clm_get_by_nodeid (struct in_addr node_id)
  */
 static int clm_confchg_fn (
 	enum totem_configuration_type configuration_type,
-    struct in_addr *member_list, int member_list_entries,
-    struct in_addr *left_list, int left_list_entries,
-    struct in_addr *joined_list, int joined_list_entries,
+    struct totem_ip_address *member_list, int member_list_entries,
+    struct totem_ip_address *left_list, int left_list_entries,
+    struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id);
 
 static void clm_sync_init (void);
@@ -122,7 +122,7 @@ static int clm_init_two_fn (struct conn_info *conn_info);
 
 static int clm_exit_fn (struct conn_info *conn_info);
 
-static int message_handler_req_exec_clm_nodejoin (void *message, struct in_addr source_addr,
+static int message_handler_req_exec_clm_nodejoin (void *message, struct totem_ip_address *source_addr,
 	int endian_conversion_required);
 
 static int message_handler_req_lib_clm_clustertrack (struct conn_info *conn_info,
@@ -170,7 +170,7 @@ struct libais_handler clm_libais_handlers[] =
 	}
 };
 
-static int (*clm_aisexec_handler_fns[]) (void *, struct in_addr source_addr, int endian_conversion_required) = {
+static int (*clm_aisexec_handler_fns[]) (void *, struct totem_ip_address *source_addr, int endian_conversion_required) = {
 	message_handler_req_exec_clm_nodejoin
 };
 	
@@ -202,12 +202,21 @@ static int clm_exec_init_fn (struct openais_config *openais_config)
 	/*
 	 * Build local cluster node data structure
 	 */
-	thisClusterNode.nodeId = this_ip->sin_addr.s_addr;
-	sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", inet_ntoa (this_ip->sin_addr));
+	sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", totemip_print (this_ip));
 	thisClusterNode.nodeAddress.length = strlen ((char *)thisClusterNode.nodeAddress.value);
+	if (this_ip->family == AF_INET) {
 	thisClusterNode.nodeAddress.family = SA_CLM_AF_INET;
-	sprintf ((char *)thisClusterNode.nodeName.value, "%s", inet_ntoa (this_ip->sin_addr));
-	thisClusterNode.nodeName.length = strlen ((char *)thisClusterNode.nodeName.value);
+	} else
+	if (this_ip->family == AF_INET6) {
+	thisClusterNode.nodeAddress.family = SA_CLM_AF_INET6;
+	} else {
+		assert (0);
+	}
+
+	strcpy ((char *)thisClusterNode.nodeName.value, (char *)thisClusterNode.nodeAddress.value);
+	thisClusterNode.nodeName.length = thisClusterNode.nodeAddress.length;
+	thisClusterNode.nodeId = this_ip->nodeid;
+	printf ("setting B to %x\n", this_ip->nodeid);
 	thisClusterNode.member = 1;
 	{
 		struct sysinfo s_info;
@@ -384,9 +393,9 @@ static int clm_nodejoin_send (void)
 
 static int clm_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 
@@ -401,36 +410,42 @@ static int clm_confchg_fn (
 	log_printf (LOG_LEVEL_NOTICE, "CLM CONFIGURATION CHANGE\n");
 	log_printf (LOG_LEVEL_NOTICE, "New Configuration:\n");
 	for (i = 0; i < member_list_entries; i++) {
-		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", inet_ntoa (member_list[i]));
+		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&member_list[i]));
 	}
 	log_printf (LOG_LEVEL_NOTICE, "Members Left:\n");
 	for (i = 0; i < left_list_entries; i++) {
-		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", inet_ntoa (left_list[i]));
+		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&left_list[i]));
 	}
 
 	log_printf (LOG_LEVEL_NOTICE, "Members Joined:\n");
 	for (i = 0; i < joined_list_entries; i++) {
-		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", inet_ntoa (joined_list[i]));
+		log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&joined_list[i]));
 	}
 
 	for (i = 0; i < left_list_entries; i++) {
-		nodes[i] = left_list[i].s_addr;
+		nodes[i] = left_list[i].nodeid;
 	}
 
 	libraryNotificationLeave (nodes, i);
+
 	/*
 	 * Load the thisClusterNode data structure in case we are
 	 * transitioning to network interface up or down
 	 */
-	thisClusterNode.nodeId = this_ip->sin_addr.s_addr;
-	strcpy ((char *)thisClusterNode.nodeName.value, (char *)inet_ntoa (this_ip->sin_addr));
-
-	sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", inet_ntoa (this_ip->sin_addr));
+	sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", totemip_print (this_ip));
 	thisClusterNode.nodeAddress.length = strlen ((char *)thisClusterNode.nodeAddress.value);
+	if (this_ip->family == AF_INET) {
 	thisClusterNode.nodeAddress.family = SA_CLM_AF_INET;
-	sprintf ((char *)thisClusterNode.nodeName.value, "%s", inet_ntoa (this_ip->sin_addr));
-	thisClusterNode.nodeName.length = strlen ((char *)thisClusterNode.nodeName.value);
-
+	} else
+	if (this_ip->family == AF_INET6) {
+	thisClusterNode.nodeAddress.family = SA_CLM_AF_INET6;
+	} else {
+		assert (0);
+	}
+	strcpy ((char *)thisClusterNode.nodeName.value,
+		(char *)thisClusterNode.nodeAddress.value);
+	thisClusterNode.nodeName.length = thisClusterNode.nodeAddress.length;
+	thisClusterNode.nodeId = this_ip->nodeid;
 	return (0);
 }
 
@@ -481,12 +496,12 @@ static void exec_clm_nodejoin_endian_conversion (struct req_exec_clm_nodejoin *i
 		SA_MAX_NAME_LENGTH);
 }
 
-static int message_handler_req_exec_clm_nodejoin (void *message, struct in_addr source_addr,
+static int message_handler_req_exec_clm_nodejoin (void *message, struct totem_ip_address *source_addr,
 	int endian_conversion_required)
 {
 	struct req_exec_clm_nodejoin *req_exec_clm_nodejoin = (struct req_exec_clm_nodejoin *)message;
 	struct req_exec_clm_nodejoin req_exec_clm_nodejoin_storage;
-	int found;
+	int found = 0;
 	int i;
 
 	if (endian_conversion_required) {
@@ -503,9 +518,7 @@ static int message_handler_req_exec_clm_nodejoin (void *message, struct in_addr
 	 * Determine if nodejoin already received
 	 */
 	for (found = 0, i = 0; i < clusterNodeEntries; i++) {
-		if (memcmp (&clusterNodes[i], &req_exec_clm_nodejoin->clusterNode, 
-			sizeof (SaClmClusterNodeT)) == 0) {
-
+		if (clusterNodes[i].nodeId == req_exec_clm_nodejoin->clusterNode.nodeId) {
 			found = 1;
 		}
 	}

+ 1 - 1
exec/clm.h

@@ -45,7 +45,7 @@ struct libclm_ci {
 	int tracking_enabled;
 };
 
-extern SaClmClusterNodeT *clm_get_by_nodeid (struct in_addr node_id);
+extern SaClmClusterNodeT *clm_get_by_nodeid (unsigned int node_id);
 
 extern struct service_handler clm_service_handler;
 

+ 20 - 14
exec/evs.c

@@ -52,6 +52,7 @@
 
 #include "../include/saAis.h"
 #include "../include/ipc_gen.h"
+#include "totemip.h"
 #include "../include/ipc_evs.h"
 #include "../include/list.h"
 #include "../include/queue.h"
@@ -73,14 +74,14 @@ static int evs_executive_initialize (struct openais_config *);
 
 static int evs_confchg_fn (
 	enum totem_configuration_type configuration_type,
-    struct in_addr *member_list, int member_list_entries,
-    struct in_addr *left_list, int left_list_entries,
-    struct in_addr *joined_list, int joined_list_entries,
+    struct totem_ip_address *member_list, int member_list_entries,
+    struct totem_ip_address *left_list, int left_list_entries,
+    struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id);
 
 static int evs_init_two_fn (struct conn_info *conn_info);
 
-static int message_handler_req_exec_mcast (void *message, struct in_addr source_addr, int endian_conversion_required);
+static int message_handler_req_exec_mcast (void *message, struct totem_ip_address *source_addr, int endian_conversion_required);
 
 static int message_handler_req_evs_join (struct conn_info *conn_info, void *message);
 static int message_handler_req_evs_leave (struct conn_info *conn_info, void *message);
@@ -124,7 +125,7 @@ struct libais_handler evs_libais_handlers[] =
 	}
 };
 
-static int (*evs_aisexec_handler_fns[]) (void *, struct in_addr source_addr, int endian_conversion_required) = {
+static int (*evs_aisexec_handler_fns[]) (void *, struct totem_ip_address *source_addr, int endian_conversion_required) = {
 	message_handler_req_exec_mcast
 };
 	
@@ -156,9 +157,9 @@ struct res_evs_confchg_callback res_evs_confchg_callback;
 
 static int evs_confchg_fn (
 	enum totem_configuration_type configuration_type,
-    struct in_addr *member_list, int member_list_entries,
-    struct in_addr *left_list, int left_list_entries,
-    struct in_addr *joined_list, int joined_list_entries,
+    struct totem_ip_address *member_list, int member_list_entries,
+    struct totem_ip_address *left_list, int left_list_entries,
+    struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 
@@ -174,15 +175,18 @@ static int evs_confchg_fn (
 	res_evs_confchg_callback.header.error = SA_OK;
 
 	for (i = 0; i < member_list_entries; i++) {
-		res_evs_confchg_callback.member_list[i].s_addr = member_list[i].s_addr;
+		totemip_copy((struct totem_ip_address *)&res_evs_confchg_callback.member_list[i],
+			&member_list[i]);
 	}
 	res_evs_confchg_callback.member_list_entries = member_list_entries;
 	for (i = 0; i < left_list_entries; i++) {
-		res_evs_confchg_callback.left_list[i].s_addr = left_list[i].s_addr;
+		totemip_copy((struct totem_ip_address *)&res_evs_confchg_callback.left_list[i],
+			&left_list[i]);
 	}
 	res_evs_confchg_callback.left_list_entries = left_list_entries;
 	for (i = 0; i < joined_list_entries; i++) {
-		res_evs_confchg_callback.joined_list[i].s_addr = joined_list[i].s_addr;
+		totemip_copy((struct totem_ip_address *)&res_evs_confchg_callback.joined_list[i],
+			&joined_list[i]);
 	}
 	res_evs_confchg_callback.joined_list_entries = joined_list_entries;
 
@@ -407,7 +411,8 @@ static int message_handler_req_evs_membership_get (struct conn_info *conn_info,
 	res_lib_evs_membership_get.header.size = sizeof (struct res_lib_evs_membership_get);
 	res_lib_evs_membership_get.header.id = MESSAGE_RES_EVS_MEMBERSHIP_GET;
 	res_lib_evs_membership_get.header.error = EVS_OK;
-	res_lib_evs_membership_get.local_addr.s_addr = this_ip->sin_addr.s_addr;
+	totemip_copy((struct totem_ip_address *)&res_lib_evs_membership_get.local_addr,
+		this_ip);
 	memcpy (&res_lib_evs_membership_get.member_list,
 		&res_evs_confchg_callback.member_list,
 		sizeof (res_lib_evs_membership_get.member_list));
@@ -421,7 +426,7 @@ static int message_handler_req_evs_membership_get (struct conn_info *conn_info,
 	return (0);
 }
 
-static int message_handler_req_exec_mcast (void *message, struct in_addr source_addr, int endian_conversion_required)
+static int message_handler_req_exec_mcast (void *message, struct totem_ip_address *source_addr, int endian_conversion_required)
 {
 	struct req_exec_evs_mcast *req_exec_evs_mcast = (struct req_exec_evs_mcast *)message;
 	struct res_evs_deliver_callback res_evs_deliver_callback;
@@ -460,7 +465,8 @@ static int message_handler_req_exec_mcast (void *message, struct in_addr source_
 		}
 
 		if (found) {
-			res_evs_deliver_callback.source_addr.s_addr = source_addr.s_addr;
+			totemip_copy((struct totem_ip_address *)&res_evs_deliver_callback.evs_address,
+				source_addr);
 			libais_send_response (conn_info, &res_evs_deliver_callback,
 				sizeof (struct res_evs_deliver_callback));
 			libais_send_response (conn_info, msg_addr,

+ 77 - 78
exec/evt.c

@@ -55,6 +55,7 @@
 #include "aispoll.h"
 #include "mempool.h"
 #include "main.h"
+#include "totemip.h"
 #include "totempg.h"
 #include "hdb.h"
 #include "clm.h"
@@ -81,9 +82,9 @@ static int lib_evt_event_data_get(struct conn_info *conn_info,
 
 static int evt_conf_change(
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id);
 
 static int evt_initialize(struct conn_info *conn_info);
@@ -157,14 +158,14 @@ static struct libais_handler evt_libais_handlers[] = {
 };
 
 	
-static int evt_remote_evt(void *msg, struct in_addr source_addr, 
+static int evt_remote_evt(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required);
-static int evt_remote_recovery_evt(void *msg, struct in_addr source_addr, 
+static int evt_remote_recovery_evt(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required);
-static int evt_remote_chan_op(void *msg, struct in_addr source_addr, 
+static int evt_remote_chan_op(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required);
 
-static int (*evt_exec_handler_fns[]) (void *m, struct in_addr s, 
+static int (*evt_exec_handler_fns[]) (void *m, struct totem_ip_address *s, 
 		int endian_conversion_required) = {
 	evt_remote_evt,
 	evt_remote_chan_op,
@@ -286,15 +287,15 @@ static struct list_head *next_retained = 0;
 static struct list_head *next_chan = 0;
 static enum recovery_phases recovery_phase = evt_recovery_complete;
 static int				left_member_count = 0;
-static struct in_addr 	*left_member_list = 0;
+static struct totem_ip_address 	*left_member_list = 0;
 static int				joined_member_count = 0;
-static struct in_addr 	*joined_member_list = 0;
+static struct totem_ip_address 	*joined_member_list = 0;
 static int			 	total_member_count = 0;
-static struct in_addr 	*current_member_list = 0;
+static struct totem_ip_address 	*current_member_list = 0;
 static int				trans_member_count = 0;
-static struct in_addr	*trans_member_list = 0;
+static struct totem_ip_address	*trans_member_list = 0;
 static int				add_count = 0;
-static struct in_addr 	*add_list = 0;
+static struct totem_ip_address 	*add_list = 0;
 static int				processed_open_counts = 0;
 
 /*
@@ -559,7 +560,7 @@ struct event_svr_channel_subscr {
  * mn_entry:			List of all nodes.
  */
 struct member_node_data {
-	struct in_addr		mn_node_addr;
+	struct totem_ip_address	mn_node_addr;
 	SaClmClusterNodeT	mn_node_info;
 	SaEvtEventIdT		mn_last_msg_id;
 	SaClmNodeIdT		mn_started;
@@ -1170,19 +1171,19 @@ static SaErrorT evt_close_channel(SaNameT *cn, uint64_t unlink_id)
 #define NODE_HASH_SIZE 256
 static struct member_node_data *nl[NODE_HASH_SIZE] = {0};
 inline int 
-hash_sock_addr(struct in_addr addr)
+hash_sock_addr(struct totem_ip_address *addr)
 {
-	return addr.s_addr & (NODE_HASH_SIZE - 1);
+	return addr->nodeid & (NODE_HASH_SIZE - 1);
 }
 
-static struct member_node_data **lookup_node(struct in_addr addr)
+static struct member_node_data **lookup_node(struct totem_ip_address *addr)
 {
 	int index = hash_sock_addr(addr);
 	struct member_node_data **nlp;
 
 	nlp = &nl[index];
 	for (nlp = &nl[index]; *nlp; nlp = &((*nlp)->mn_next)) {
-		if ((*nlp)->mn_node_addr.s_addr == addr.s_addr) {
+		if (totemip_equal(&(*nlp)->mn_node_addr, addr)) {
 			break;
 		}
 	}
@@ -1191,7 +1192,7 @@ static struct member_node_data **lookup_node(struct in_addr addr)
 }
 
 static struct member_node_data *
-evt_find_node(struct in_addr addr)
+evt_find_node(struct totem_ip_address *addr)
 {
 	struct member_node_data **nlp;
 
@@ -1206,7 +1207,7 @@ evt_find_node(struct in_addr addr)
 }
 
 static SaErrorT
-evt_add_node(struct in_addr addr, SaClmClusterNodeT *cn) 
+evt_add_node(struct totem_ip_address *addr, SaClmClusterNodeT *cn) 
 {
 	struct member_node_data **nlp;
 	struct member_node_data *nl;
@@ -1231,7 +1232,7 @@ evt_add_node(struct in_addr addr, SaClmClusterNodeT *cn)
 	if (nl) {
 		memset(nl, 0, sizeof(*nl));
 		err = SA_AIS_OK;
-		nl->mn_node_addr = addr;
+		totemip_copy(&nl->mn_node_addr, addr);
 		nl->mn_started = 1;
 	}
 	list_init(&nl->mn_entry);
@@ -1256,11 +1257,11 @@ static struct member_node_data* oldest_node()
 	int i;
 
 	for (i = 0; i < trans_member_count; i++) {
-		mn = evt_find_node(trans_member_list[i]);
+		mn = evt_find_node(&trans_member_list[i]);
 		if (!mn || (mn->mn_started == 0)) {
 			log_printf(LOG_LEVEL_ERROR, 
 				"Transitional config Node %s not active\n",
-				inet_ntoa(trans_member_list[i]));
+				totemip_print(&trans_member_list[i]));
 			continue;
 		}
 		if ((oldest == NULL) || 
@@ -1285,7 +1286,7 @@ static struct member_node_data* oldest_node()
  * a new node.
  */
 static int check_last_event(struct lib_event_data *evtpkt, 
-				struct in_addr addr)
+				struct totem_ip_address *addr)
 {
 	struct member_node_data *nd;
 	SaClmClusterNodeT *cn;
@@ -1296,7 +1297,7 @@ static int check_last_event(struct lib_event_data *evtpkt,
 		log_printf(LOG_LEVEL_DEBUG, 
 				"Node ID 0x%x not found for event %llx\n",
 				evtpkt->led_publisher_node_id, evtpkt->led_event_id);
-		cn = clm_get_by_nodeid(addr);
+		cn = clm_get_by_nodeid(addr->nodeid);
 		if (!cn) {
 			log_printf(LOG_LEVEL_DEBUG, 
 					"Cluster Node 0x%x not found for event %llx\n",
@@ -1964,8 +1965,8 @@ static void retain_event(struct event_data *evt)
 				"retention of event id 0x%llx failed\n",
 				evt->ed_event.led_event_id);
 	} else {
-		log_printf(RETENTION_TIME_DEBUG, "Retain event ID 0x%llx\n", 
-					evt->ed_event.led_event_id);
+		log_printf(RETENTION_TIME_DEBUG, "Retain event ID 0x%llx for %u ms\n", 
+					evt->ed_event.led_event_id, msec_in_future);
 	}
 }
 
@@ -2769,9 +2770,9 @@ static void remove_chan_open_info(SaClmNodeIdT node_id)
  */
 static int evt_conf_change(
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id)
 {
 	log_printf(RECOVERY_DEBUG, "Evt conf change %d\n", 
@@ -2801,7 +2802,7 @@ static int evt_conf_change(
 		}
 		if (left_list_entries) {
 			left_member_list = 
-				malloc(sizeof(struct in_addr) * left_list_entries);
+				malloc(sizeof(struct totem_ip_address) * left_list_entries);
 			if (!left_member_list) {
 				/* 
 			 	 * ERROR: No recovery.
@@ -2811,7 +2812,7 @@ static int evt_conf_change(
 				assert(0);
 			}
 			memcpy(left_member_list, left_list, 
-					sizeof(struct in_addr) * left_list_entries);
+					sizeof(struct totem_ip_address) * left_list_entries);
 		}
 
 		if (trans_member_list) {
@@ -2820,7 +2821,7 @@ static int evt_conf_change(
 		}
 		if (member_list_entries) {
 			trans_member_list = 
-				malloc(sizeof(struct in_addr) * member_list_entries);
+				malloc(sizeof(struct totem_ip_address) * member_list_entries);
 
 			if (!trans_member_list) {
 				/* 
@@ -2831,7 +2832,7 @@ static int evt_conf_change(
 				assert(0);
 			}
 			memcpy(trans_member_list, member_list, 
-					sizeof(struct in_addr) * member_list_entries);
+					sizeof(struct totem_ip_address) * member_list_entries);
 		}
 	}
 
@@ -2846,7 +2847,7 @@ static int evt_conf_change(
 		}
 		if (joined_list_entries) {
 			joined_member_list = 
-				malloc(sizeof(struct in_addr) * joined_list_entries);
+				malloc(sizeof(struct totem_ip_address) * joined_list_entries);
 			if (!joined_member_list) {
 				/* 
 			 	 * ERROR: No recovery.
@@ -2856,7 +2857,7 @@ static int evt_conf_change(
 				assert(0);
 			}
 			memcpy(joined_member_list, joined_list, 
-					sizeof(struct in_addr) * joined_list_entries);
+					sizeof(struct totem_ip_address) * joined_list_entries);
 		}
 
 
@@ -2866,7 +2867,7 @@ static int evt_conf_change(
 		}
 		if (member_list_entries) {
 			current_member_list = 
-				malloc(sizeof(struct in_addr) * member_list_entries);
+				malloc(sizeof(struct totem_ip_address) * member_list_entries);
 
 			if (!current_member_list) {
 				/* 
@@ -2877,7 +2878,7 @@ static int evt_conf_change(
 				assert(0);
 			}
 			memcpy(current_member_list, member_list, 
-					sizeof(struct in_addr) * member_list_entries);
+					sizeof(struct totem_ip_address) * member_list_entries);
 		}
 	}
 
@@ -3041,7 +3042,7 @@ try_deliver_event(struct event_data *evt,
 /*
  * Receive the network event message and distribute it to local subscribers
  */
-static int evt_remote_evt(void *msg, struct in_addr source_addr, 
+static int evt_remote_evt(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required)
 {
 	/*
@@ -3057,19 +3058,19 @@ static int evt_remote_evt(void *msg, struct in_addr source_addr,
 	SaClmClusterNodeT *cn;
 
 	log_printf(LOG_LEVEL_DEBUG, "Remote event data received from %s\n",
-					inet_ntoa(source_addr));
+					totemip_print(source_addr));
 
 	/*
 	 * See where the message came from so that we can set the 
 	 * publishing node id in the message before delivery.
 	 */
-	cn = clm_get_by_nodeid (source_addr);
+	cn = clm_get_by_nodeid (source_addr->nodeid);
 	if (!cn) {
 			/*
 			 * Not sure how this can happen...
 			 */
 			log_printf(LOG_LEVEL_DEBUG, "No cluster node data for %s\n",
-							inet_ntoa(source_addr));
+							totemip_print(source_addr));
 			errno = ENXIO;
 			return -1;
 	}
@@ -3081,7 +3082,7 @@ static int evt_remote_evt(void *msg, struct in_addr source_addr,
 	}
 
 	evtpkt->led_publisher_node_id = cn->nodeId;
-	evtpkt->led_in_addr = source_addr;
+	totemip_copy(&evtpkt->led_addr, source_addr);
 	evtpkt->led_receive_time = clust_time_now();
 
 	if (evtpkt->led_chan_unlink_id != EVT_CHAN_ACTIVE) {
@@ -3153,7 +3154,7 @@ inline SaTimeT calc_retention_time(SaTimeT retention,
 /*
  * Receive a recovery network event message and save it in the retained list
  */
-static int evt_remote_recovery_evt(void *msg, struct in_addr source_addr, 
+static int evt_remote_recovery_evt(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required)
 {
 	/*
@@ -3174,7 +3175,7 @@ static int evt_remote_recovery_evt(void *msg, struct in_addr source_addr,
 
 	log_printf(RECOVERY_EVENT_DEBUG, 
 			"Remote recovery event data received from %s\n",
-					inet_ntoa(source_addr));
+					totemip_print(source_addr));
 
 	if (recovery_phase == evt_recovery_complete) {
 		log_printf(RECOVERY_EVENT_DEBUG, 
@@ -3211,19 +3212,19 @@ static int evt_remote_recovery_evt(void *msg, struct in_addr source_addr,
 	 * If we haven't seen this event yet and it has remaining time, process
 	 * the event.
 	 */
-	if (!check_last_event(evtpkt, evtpkt->led_in_addr) && 
+	if (!check_last_event(evtpkt, &evtpkt->led_addr) && 
 												evtpkt->led_retention_time) {
 		/*
 		 * See where the message came from so that we can set the 
 		 * publishing node id in the message before delivery.
 		 */
-		md = evt_find_node(evtpkt->led_in_addr);
+		md = evt_find_node(&evtpkt->led_addr);
 		if (!md) {
 				/*
 				 * Not sure how this can happen
 				 */
 				log_printf(LOG_LEVEL_NOTICE, "No node for %s\n",
-								inet_ntoa(evtpkt->led_in_addr));
+								totemip_print(&evtpkt->led_addr));
 				errno = ENXIO;
 				return -1;
 		}
@@ -3468,8 +3469,8 @@ convert_chan_packet(struct req_evt_chan_command *cpkt)
 		break;
 
 	case EVT_SET_ID_OP:
-		cpkt->u.chc_set_id.chc_addr.s_addr = 
-			swab32(cpkt->u.chc_set_id.chc_addr.s_addr);
+		cpkt->u.chc_set_id.chc_nodeid = 
+			swab32(cpkt->u.chc_set_id.chc_nodeid);
 		cpkt->u.chc_set_id.chc_last_id = swab64(cpkt->u.chc_set_id.chc_last_id);
 		break;
 
@@ -3501,11 +3502,11 @@ convert_chan_packet(struct req_evt_chan_command *cpkt)
  * Used to communicate channel opens/closes, clear retention time,
  * config change updates...
  */
-static int evt_remote_chan_op(void *msg, struct in_addr source_addr, 
+static int evt_remote_chan_op(void *msg, struct totem_ip_address *source_addr, 
 		int endian_conversion_required)
 {
 	struct req_evt_chan_command *cpkt = msg;
-	struct in_addr local_node = {SA_CLM_LOCAL_NODE_ID};
+	unsigned int local_node = {SA_CLM_LOCAL_NODE_ID};
 	SaClmClusterNodeT *cn, *my_node;
 	struct member_node_data *mn;
 	struct event_svr_channel_instance *eci;
@@ -3520,11 +3521,11 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 
 	mn = evt_find_node(source_addr);
 	if (mn == NULL) {
-		cn = clm_get_by_nodeid(source_addr);
+		cn = clm_get_by_nodeid(source_addr->nodeid);
 		if (cn == NULL) {
 			log_printf(LOG_LEVEL_WARNING, 
 				"Evt remote channel op: Node data for addr %s is NULL\n",
-					inet_ntoa(source_addr));
+					totemip_print(source_addr));
 			return 0;
 		} else {
 			evt_add_node(source_addr, cn);
@@ -3709,24 +3710,22 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 	 * start using an event ID that is unique.
 	 */
 	case EVT_SET_ID_OP: {
-		struct in_addr my_addr;
 		int log_level = LOG_LEVEL_DEBUG;
-		my_addr.s_addr = my_node->nodeId;
-		if (cpkt->u.chc_set_id.chc_addr.s_addr == my_addr.s_addr) {
+		if (cpkt->u.chc_set_id.chc_nodeid == my_node->nodeId) {
 			log_level = RECOVERY_DEBUG;
 		}
 		log_printf(log_level, 
 			"Received Set event ID OP from %s to %llx for %x my addr %x base %llx\n",
-					inet_ntoa(source_addr), 
+					totemip_print(source_addr), 
 					cpkt->u.chc_set_id.chc_last_id,
-					cpkt->u.chc_set_id.chc_addr.s_addr,
-					my_addr.s_addr,
+					cpkt->u.chc_set_id.chc_nodeid,
+					my_node->nodeId,
 					base_id);	
-		if (cpkt->u.chc_set_id.chc_addr.s_addr == my_addr.s_addr) {
+		if (cpkt->u.chc_set_id.chc_nodeid == my_node->nodeId) {
 			if (cpkt->u.chc_set_id.chc_last_id >= base_id) {
 				log_printf(RECOVERY_DEBUG, 
 					"Set event ID from %s to %llx\n",
-					inet_ntoa(source_addr), cpkt->u.chc_set_id.chc_last_id);	
+					totemip_print(source_addr), cpkt->u.chc_set_id.chc_last_id);	
 				base_id = cpkt->u.chc_set_id.chc_last_id + 1;
 			}
 		}
@@ -3742,7 +3741,7 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 		if (recovery_phase == evt_recovery_complete) {
 			log_printf(LOG_LEVEL_ERROR, 
 				"Evt open count msg from %s, but not in membership change\n",
-				inet_ntoa(source_addr));
+				totemip_print(source_addr));
 		}
 
 		/*
@@ -3786,15 +3785,15 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 		if (recovery_phase == evt_recovery_complete) {
 			log_printf(LOG_LEVEL_ERROR, 
 				"Evt config msg from %s, but not in membership change\n",
-				inet_ntoa(source_addr));
+				totemip_print(source_addr));
 		}
 		log_printf(RECOVERY_DEBUG, 
 			"Receive EVT_CONF_CHANGE_DONE from %s members %d checked in %d\n",
-				inet_ntoa(source_addr), total_member_count, checked_in+1);
+				totemip_print(source_addr), total_member_count, checked_in+1);
 		if (!mn) {
 			log_printf(RECOVERY_DEBUG, 
 				"NO NODE DATA AVAILABLE FOR %s\n",
-					inet_ntoa(source_addr));
+					totemip_print(source_addr));
 		}
 
 		if (++checked_in == total_member_count) {
@@ -3825,7 +3824,7 @@ static int evt_remote_chan_op(void *msg, struct in_addr source_addr,
 	case EVT_CONF_DONE: {
 		log_printf(RECOVERY_DEBUG, 
 				"Receive EVT_CONF_DONE from %s, members %d checked in %d\n", 
-				inet_ntoa(source_addr),
+				totemip_print(source_addr),
 					total_member_count, checked_in+1);
 		if (++checked_in == total_member_count) {
 			/*
@@ -3857,9 +3856,9 @@ static void evt_sync_init(void)
 {
 	SaClmClusterNodeT *cn;
 	struct member_node_data *md;
-	struct in_addr my_node = {SA_CLM_LOCAL_NODE_ID};
+	unsigned int my_node = {SA_CLM_LOCAL_NODE_ID};
 	int left_list_entries = left_member_count;
-	struct in_addr *left_list = left_member_list;
+ 	struct totem_ip_address *left_list = left_member_list;
 
 	log_printf(RECOVERY_DEBUG, "Evt synchronize initialization\n");
 
@@ -3877,17 +3876,17 @@ static void evt_sync_init(void)
 	 * account for nodes that left the membership
 	 */
 	while (left_list_entries--) {
-		md = evt_find_node(*left_list);
+		md = evt_find_node(left_list);
 		if (md == 0) {
 			log_printf(LOG_LEVEL_WARNING, 
 					"Can't find cluster node at %s\n",
-							inet_ntoa(left_list[0]));
+							totemip_print(&left_list[0]));
 		/*
 		 * Mark this one as down.
 		 */
 		} else {
 			log_printf(RECOVERY_DEBUG, "cluster node at %s down\n",
-							inet_ntoa(left_list[0]));
+							totemip_print(&left_list[0]));
 			md->mn_started = 0;
 			remove_chan_open_info(md->mn_node_info.nodeId);
 		}
@@ -3970,17 +3969,17 @@ static int evt_sync_process(void)
 			 * that we've seen from him.  He will set his base ID for
 			 * generating event and message IDs to the highest one seen.
 			 */
-			md = evt_find_node(*add_list);
+			md = evt_find_node(add_list);
 			if (md != NULL) {
 				log_printf(RECOVERY_DEBUG, 
 					"Send set evt ID %llx to %s\n",
-					md->mn_last_msg_id, inet_ntoa(*add_list));
+					md->mn_last_msg_id, totemip_print(add_list));
 				md->mn_started = 1;
 				memset(&cpkt, 0, sizeof(cpkt));
 				cpkt.chc_head.id = MESSAGE_REQ_EXEC_EVT_CHANCMD;
 				cpkt.chc_head.size = sizeof(cpkt);
 				cpkt.chc_op = EVT_SET_ID_OP;
-				cpkt.u.chc_set_id.chc_addr = *add_list;
+				cpkt.u.chc_set_id.chc_nodeid = add_list->nodeid;
 				cpkt.u.chc_set_id.chc_last_id = md->mn_last_msg_id;
 				chn_iovec.iov_base = &cpkt;
 				chn_iovec.iov_len = cpkt.chc_head.size;
@@ -3988,7 +3987,7 @@ static int evt_sync_process(void)
 				if (res != 0) {
 					log_printf(RECOVERY_DEBUG, 
 						"Unable to send event id to %s\n", 
-						inet_ntoa(*add_list));
+						totemip_print(add_list));
 					/*
 					 * We'll try again later.
 					 */
@@ -3999,17 +3998,17 @@ static int evt_sync_process(void)
 				/*
 				 * Not seen before, add it to our list of nodes.
 				 */
-				cn = clm_get_by_nodeid(*add_list);
+				cn = clm_get_by_nodeid(add_list->nodeid);
 				if (!cn) {
 					/*
 					 * Error: shouldn't happen
 					 */
 					log_printf(LOG_LEVEL_ERROR,
 							"recovery error node: %s not found\n",
-							inet_ntoa(*add_list));
+							totemip_print(add_list));
 					assert(0);
 				} else {
-					evt_add_node(*add_list, cn);
+					evt_add_node(add_list, cn);
 				}
 			}
 

+ 4 - 4
exec/handlers.h

@@ -54,13 +54,13 @@ struct libais_handler {
 struct service_handler {
 	struct libais_handler *libais_handlers;
 	int libais_handlers_count;
-	int (**aisexec_handler_fns) (void *msg, struct in_addr source_addr, int endian_conversion_needed);
+	int (**aisexec_handler_fns) (void *msg, struct totem_ip_address *source_addr, int endian_conversion_needed);
 	int aisexec_handler_fns_count;
 	int (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id);
 	int (*libais_init_fn) (struct conn_info *conn_info, void *msg);
 	int (*libais_init_two_fn) (struct conn_info *conn_info);

+ 2 - 0
exec/lck.c

@@ -518,8 +518,10 @@ static int lck_exec_init_fn (struct openais_config *openais_config)
 	/*
 	 *  Initialize the saved ring ID.
 	 */
+#ifdef TODO
 	saved_ring_id.seq = 0;
 	saved_ring_id.rep.s_addr = this_ip->sin_addr.s_addr;		
+#endif
 	
 	return (0);
 }

+ 14 - 14
exec/main.c

@@ -183,8 +183,8 @@ static void sigusr2_handler (int num)
 	return;
 }
 
-struct sockaddr_in *this_ip;
-struct sockaddr_in this_non_loopback_ip;
+struct totem_ip_address *this_ip;
+struct totem_ip_address this_non_loopback_ip;
 #define LOCALHOST_IP inet_addr("127.0.0.1")
 
 char *socketname = "libais.socket";
@@ -787,7 +787,7 @@ static int pool_sizes[] = { 0, 0, 0, 0, 0, 4096, 0, 1, 0, /* 256 */
 					1024, 0, 1, 4096, 0, 0, 0, 0, /* 65536 */
 					1, 1, 1, 1, 1, 1, 1, 1, 1 };
 
-static int (*aisexec_handler_fns[AIS_SERVICE_HANDLER_AISEXEC_FUNCTIONS_MAX]) (void *msg, struct in_addr source_addr, int endian_conversion_required);
+static int (*aisexec_handler_fns[AIS_SERVICE_HANDLER_AISEXEC_FUNCTIONS_MAX]) (void *msg, struct totem_ip_address *source_addr, int endian_conversion_required);
 static int aisexec_handler_fns_count = 1;
 
 /*
@@ -838,7 +838,7 @@ void aisexec_sync_fns_build (void)
 char delivery_data[MESSAGE_SIZE_MAX];
 
 static void deliver_fn (
-	struct in_addr source_addr,
+	struct totem_ip_address *source_addr,
 	struct iovec *iovec,
 	int iov_len,
 	int endian_conversion_required)
@@ -876,15 +876,15 @@ static void deliver_fn (
 
 static void confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 	int i;
 
-	if (this_ip->sin_addr.s_addr != LOCALHOST_IP) {
-		memcpy(&this_non_loopback_ip, this_ip, sizeof(struct sockaddr_in));
+	if (!totemip_localhost_check(this_ip)) {
+		totemip_copy(&this_non_loopback_ip, this_ip);
 	}
 
 	/*
@@ -1047,8 +1047,8 @@ static void aisexec_mlockall (void)
 int message_source_is_local(struct message_source *source)
 {
 	int ret = 0;
-	if ((source->in_addr.s_addr == LOCALHOST_IP)
-		||(source->in_addr.s_addr == this_non_loopback_ip.sin_addr.s_addr)) {
+	if ((totemip_localhost_check(&source->addr)
+	     ||(totemip_equal(&source->addr, &this_non_loopback_ip)))) {
 		ret = 1;
 	}
 	return ret;	
@@ -1056,7 +1056,7 @@ int message_source_is_local(struct message_source *source)
 
 void message_source_set (struct message_source *source, struct conn_info *conn_info)
 {
-	source->in_addr.s_addr = this_ip->sin_addr.s_addr;
+	totemip_copy(&source->addr, this_ip);
 	source->conn_info = conn_info;
 }
 
@@ -1071,9 +1071,9 @@ int main (int argc, char **argv)
 	char *error_string;
 	struct openais_config openais_config;
 
-	memset(&this_non_loopback_ip, 0, sizeof(struct sockaddr_in));
+	memset(&this_non_loopback_ip, 0, sizeof(struct totem_ip_address));
 
-	this_non_loopback_ip.sin_addr.s_addr = LOCALHOST_IP;
+	totemip_localhost(AF_INET, &this_non_loopback_ip);
 
 	aisexec_uid_determine ();
 

+ 1 - 1
exec/main.h

@@ -146,7 +146,7 @@ enum nodeexec_message_types {
 	MESSAGE_REQ_EXEC_LCK_LOCKPURGE = 30
 };
 
-extern struct sockaddr_in *this_ip;
+extern struct totem_ip_address *this_ip;
 
 poll_handle aisexec_poll_handle;
 

+ 1 - 1
exec/mainparse.h

@@ -147,7 +147,7 @@ struct saAmfComponent {
 	int registered;
 	int local;
 	struct conn_info *conn_info;
-	struct in_addr source_addr;
+	struct totem_ip_address source_addr;
 	SaNameT name;
 	SaAmfReadinessStateT currentReadinessState;
 	SaAmfReadinessStateT newReadinessState;

+ 7 - 7
exec/sync.c

@@ -59,7 +59,7 @@
 #define LOG_SERVICE LOG_SERVICE_SYNC
 
 struct barrier_data {
-	struct in_addr addr;
+	struct totem_ip_address addr;
 	int completed;
 };
 
@@ -208,9 +208,9 @@ void sync_register (
 
 void sync_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 	int i;
@@ -228,7 +228,7 @@ void sync_confchg_fn (
 	sync_recovery_index = 0;
 	memset (&barrier_data_confchg, 0, sizeof (barrier_data_confchg));
 	for (i = 0; i < member_list_entries; i++) {
-		barrier_data_confchg[i].addr.s_addr = member_list[i].s_addr;
+		totemip_copy(&barrier_data_confchg[i].addr, &member_list[i]);
 		barrier_data_confchg[i].completed = 0;
 	}
 	memcpy (barrier_data_process, barrier_data_confchg,
@@ -239,7 +239,7 @@ void sync_confchg_fn (
 
 static struct memb_ring_id deliver_ring_id;
 
-int sync_deliver_fn (void *msg, struct in_addr source_addr,
+int sync_deliver_fn (void *msg, struct totem_ip_address *source_addr,
 	int endian_conversion_needed)
 {
 	struct req_exec_sync_barrier_start *req_exec_sync_barrier_start =
@@ -265,7 +265,7 @@ int sync_deliver_fn (void *msg, struct in_addr source_addr,
 	 * Set completion for source_addr's address
 	 */
 	for (i = 0; i < barrier_data_confchg_entries; i++) {
-		if (source_addr.s_addr == barrier_data_process[i].addr.s_addr) {
+		if (totemip_equal(source_addr,  &barrier_data_process[i].addr)) {
 			barrier_data_process[i].completed = 1;
 			break;
 		}

+ 4 - 4
exec/sync.h

@@ -53,12 +53,12 @@ void sync_register (totemsrp_handle handle,
 
 void sync_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id);
 
-int sync_deliver_fn (void *msg, struct in_addr source_addr,
+int sync_deliver_fn (void *msg, struct totem_ip_address *source_addr,
 	int endian_conversion_needed);
 
 int sync_in_process (void);

+ 8 - 5
exec/totem.h

@@ -33,9 +33,10 @@
  */
 #ifndef TOTEM_H_DEFINED
 #define TOTEM_H_DEFINED
+#include "totemip.h"
 
 #define MESSAGE_SIZE_MAX			256000
-#define PROCESSOR_COUNT_MAX			16
+#define PROCESSOR_COUNT_MAX			32
 #define FRAME_SIZE_MAX				9000
 #define SEND_THREADS_MAX			16
 
@@ -60,8 +61,8 @@ enum {
 } totem_timeout_types;
 
 struct totem_interface {
-	struct sockaddr_in bindnet;
-	struct sockaddr_in boundto;
+	struct totem_ip_address bindnet;
+	struct totem_ip_address boundto;
 };
 
 struct totem_logging_configuration {
@@ -81,7 +82,9 @@ struct totem_config {
 	 */
 	struct totem_interface *interfaces;
 	int interface_count;
-	struct sockaddr_in mcast_addr;
+	struct totem_ip_address mcast_addr;
+	uint16_t ip_port;
+	int node_id;
 
 	/*
 	 * key information
@@ -138,7 +141,7 @@ enum totem_callback_token_type {
 };
 
 struct memb_ring_id {
-	struct in_addr rep;
+	struct totem_ip_address rep;
 	unsigned long long seq;
 } __attribute__((packed));
 

+ 26 - 7
exec/totemconfig.c

@@ -150,7 +150,6 @@ extern int totem_config_read (
 	memset (totem_config->interfaces, 0,
 		sizeof (struct totem_interface) * interface_max);
 
-	totem_config->mcast_addr.sin_family = AF_INET;
 	totem_config->secauth = 1;
 
 	fp = fopen ("/etc/ais/openais.conf", "r");
@@ -215,14 +214,17 @@ extern int totem_config_read (
 			if ((loc = strstr_rs (line, "threads:"))) {
 				totem_config->threads = atoi (loc);
 			} else
+			if ((loc = strstr_rs (line, "nodeid:"))) {
+				res = totem_config->node_id = atoi (loc);
+			} else
 			if ((loc = strstr_rs (line, "netmtu:"))) {
 				totem_config->net_mtu = atoi (loc);
 			} else
 			if ((loc = strstr_rs (line, "mcastaddr:"))) {
-				res = inet_aton (loc, &totem_config->mcast_addr.sin_addr);
+				res = totemip_parse (&totem_config->mcast_addr, loc);
 			} else
 			if ((loc = strstr_rs (line, "mcastport:"))) {
-				res = totem_config->mcast_addr.sin_port = htons (atoi (loc));
+				res = totem_config->ip_port = htons (atoi (loc));
 			} else
 			if ((loc = strstr_rs (line, "bindnetaddr:"))) {
 				if (interface_max == totem_config->interface_count) {
@@ -231,8 +233,7 @@ extern int totem_config_read (
 					totem_config->interface_count);
 					goto parse_error;
 				}
-				res = inet_aton (loc,
-					&totem_config->interfaces[totem_config->interface_count].bindnet.sin_addr);
+				res = totemip_parse (&totem_config->interfaces[totem_config->interface_count].bindnet, loc);
 				totem_config->interface_count += 1;
 			} else
 			if ((loc = strstr_rs (line, "token:"))) {
@@ -305,16 +306,23 @@ int totem_config_validate (
 	/*
 	 * Some error checking of parsed data to make sure its valid
 	 */
-	if (totem_config->mcast_addr.sin_addr.s_addr == 0) {
+	if ((int *)&totem_config->mcast_addr.addr == 0) {
 		error_reason = "No multicast address specified";
 		goto parse_error;
 	}
 
-	if (totem_config->mcast_addr.sin_port == 0) {
+	if (totem_config->ip_port == 0) {
 		error_reason = "No multicast port specified";
 		goto parse_error;
 	}
 
+	if (totem_config->mcast_addr.family == AF_INET6 &&
+		totem_config->node_id == 0) {
+
+		error_reason = "An IPV6 network requires that a node ID be specified.";
+		goto parse_error;
+	}
+
 	if (totem_config->interface_count == 0) {
 		error_reason = "No bindnet specified";
 		goto parse_error;
@@ -470,6 +478,7 @@ int totem_config_keyread (
 {
 	int fd;
 	int res;
+	int i;
 
 	if (totem_config->secauth == 0) {
 		return (0);
@@ -497,6 +506,16 @@ int totem_config_keyread (
 			res * 8, key_location);
 		goto parse_error;
 	}
+	if (totem_config->mcast_addr.family != totem_config->interfaces[0].bindnet.family) {
+		strcpy (error_string_response, "Multicast address family does not match bind address family");
+		goto parse_error;
+	}
+	for (i = 0; i < totem_config->interface_count; i++) {
+		if (totem_config->mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
+			strcpy (error_string_response, "Not all bind address belong to the same IP family");
+			goto parse_error;
+		}
+	}
 	return (0);
 
 parse_error:

+ 366 - 0
exec/totemip.c

@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2005 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@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.
+ */
+
+/* IPv4/6 abstraction */
+
+#include <netinet/in.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+/* ARGH!! I hate netlink */
+#include <asm/types.h>
+#include <linux/rtnetlink.h>
+
+#include "totemip.h"
+
+#define LOCALHOST_IPV4 "127.0.0.1"
+#define LOCALHOST_IPV6 "::1"
+
+#define NETLINK_BUFSIZE 16384
+
+/* Compare two addresses */
+int totemip_equal(struct totem_ip_address *addr1, struct totem_ip_address *addr2)
+{
+	int addrlen = 0;
+
+	if (addr1->family != addr2->family)
+		return 0;
+
+	if (addr1->family == AF_INET) {
+		addrlen = sizeof(struct in_addr);
+	}
+	if (addr1->family == AF_INET6) {
+		addrlen = sizeof(struct in6_addr);
+	}
+	assert(addrlen);
+
+	if (memcmp(addr1->addr, addr2->addr, addrlen) == 0)
+		return 1;
+	else
+		return 0;
+
+}
+
+/* Copy a totem_ip_address */
+void totemip_copy(struct totem_ip_address *addr1, struct totem_ip_address *addr2)
+{
+	memcpy(addr1, addr2, sizeof(struct totem_ip_address));
+}
+
+/* For sorting etc. params are void * for qsort's benefit */
+int totemip_compare(const void *a, const void *b)
+{
+	int i;
+	const struct totem_ip_address *addr1 = a;
+	const struct totem_ip_address *addr2 = b;
+	struct in6_addr *sin6a;
+	struct in6_addr *sin6b;
+
+	if (addr1->family != addr2->family)
+		return (addr1->family > addr2->family);
+
+	if (addr1->family == AF_INET) {
+		struct in_addr *in1 = (struct in_addr *)addr1->addr;
+		struct in_addr *in2 = (struct in_addr *)addr2->addr;
+
+		/* A bit clunky but avoids sign problems */
+		if (in1->s_addr == in2->s_addr)
+			return 0;
+		if (htonl(in1->s_addr) < htonl(in2->s_addr))
+			return -1;
+		else
+			return +1;
+	}
+
+	/* Compare IPv6 addresses */
+	sin6a = (struct in6_addr *)addr1->addr;
+	sin6b = (struct in6_addr *)addr2->addr;
+
+	/* Remember, addresses are in big-endian format.
+	   We compare 16bits at a time rather than 32 to avoid sign problems */
+	for (i = 0; i < 8; i++) {
+		int res = htons(sin6a->s6_addr16[i]) -
+			htons(sin6b->s6_addr16[i]);
+		if (res) {
+			return res;
+		}
+	}
+	return 0;
+}
+
+/* Build a localhost totem_ip_address */
+int totemip_localhost(int family, struct totem_ip_address *localhost)
+{
+	char *addr_text;
+
+	if (family == AF_INET)
+		addr_text = LOCALHOST_IPV4;
+	else
+		addr_text = LOCALHOST_IPV6;
+
+	if (inet_pton(family, addr_text, (char *)localhost->addr) <= 0)
+		return -1;
+
+	return 0;
+}
+
+int totemip_localhost_check(struct totem_ip_address *addr)
+{
+	struct totem_ip_address localhost;
+
+	if (totemip_localhost(addr->family, &localhost))
+		return 0;
+	return totemip_equal(addr, &localhost);
+}
+
+const char *totemip_print(struct totem_ip_address *addr)
+{
+	static char buf[INET6_ADDRSTRLEN];
+
+	return inet_ntop(addr->family, addr->addr, buf, sizeof(buf));
+}
+
+/* Make a totem_ip_address into a usable sockaddr_storage */
+int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
+					uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
+{
+	int ret = -1;
+
+	if (ip_addr->family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
+
+		memset(sin, 0, sizeof(struct sockaddr_in));
+		sin->sin_family = ip_addr->family;
+		sin->sin_port = port;
+		memcpy(&sin->sin_addr, ip_addr->addr, sizeof(struct in_addr));
+
+		*addrlen = sizeof(struct sockaddr_in);
+		ret = 0;
+	}
+
+	if (ip_addr->family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)saddr;
+
+		memset(sin, 0, sizeof(struct sockaddr_in6));
+		sin->sin6_family = ip_addr->family;
+		sin->sin6_port = port;
+		sin->sin6_scope_id = 2;
+		memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr));
+
+		*addrlen = sizeof(struct sockaddr_in6);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* Converts an address string string into a totem_ip_address */
+int totemip_parse(struct totem_ip_address *totemip, char *addr)
+{
+        struct addrinfo *ainfo;
+        struct addrinfo ahints;
+	struct sockaddr_in *sa;
+	struct sockaddr_in6 *sa6;
+	int ret;
+
+        memset(&ahints, 0, sizeof(ahints));
+        ahints.ai_socktype = SOCK_DGRAM;
+        ahints.ai_protocol = IPPROTO_UDP;
+
+        /* Lookup the nodename address */
+        ret = getaddrinfo(addr, NULL, &ahints, &ainfo);
+	if (ret)
+		return -errno;
+
+	sa = (struct sockaddr_in *)ainfo->ai_addr;
+	sa6 = (struct sockaddr_in6 *)ainfo->ai_addr;
+	totemip->family = ainfo->ai_family;
+
+	if (ainfo->ai_family == AF_INET)
+		memcpy(totemip->addr, &sa->sin_addr, sizeof(struct in_addr));
+	else
+		memcpy(totemip->addr, &sa6->sin6_addr, sizeof(struct in6_addr));
+
+	return 0;
+}
+
+/* Make a sockaddr_* into a totem_ip_address */
+int totemip_sockaddr_to_totemip_convert(struct sockaddr_storage *saddr, struct totem_ip_address *ip_addr)
+{
+	int ret = -1;
+
+	ip_addr->family = saddr->ss_family;
+	ip_addr->nodeid = 0;
+
+	if (saddr->ss_family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
+
+		memcpy(ip_addr->addr, &sin->sin_addr, sizeof(struct in_addr));
+		ret = 0;
+	}
+
+	if (saddr->ss_family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)saddr;
+
+		memcpy(ip_addr->addr, &sin->sin6_addr, sizeof(struct in6_addr));
+
+		ret = 0;
+	}
+	return ret;
+}
+
+int totemip_iface_check(struct totem_ip_address *bindnet,
+			struct totem_ip_address *boundto,
+			int *interface_up,
+			int *interface_num)
+{
+	int fd;
+	struct {
+                struct nlmsghdr nlh;
+                struct rtgenmsg g;
+        } req;
+        struct sockaddr_nl nladdr;
+	static char rcvbuf[NETLINK_BUFSIZE];
+
+	*interface_up = 0;
+	*interface_num = 0;
+
+	/* Ask netlink for a list of interface addresses */
+	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (fd <0)
+		return -1;
+
+        setsockopt(fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf));
+
+        memset(&nladdr, 0, sizeof(nladdr));
+        nladdr.nl_family = AF_NETLINK;
+
+        req.nlh.nlmsg_len = sizeof(req);
+        req.nlh.nlmsg_type = RTM_GETADDR;
+        req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+        req.nlh.nlmsg_pid = 0;
+        req.nlh.nlmsg_seq = 1;
+        req.g.rtgen_family = bindnet->family;
+
+        if (sendto(fd, (void *)&req, sizeof(req), 0,
+		   (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0)  {
+		close(fd);
+		return -1;
+	}
+
+	/* Look through the return buffer for our address */
+	while (1)
+	{
+		int status;
+		struct nlmsghdr *h;
+		struct iovec iov = { rcvbuf, sizeof(rcvbuf) };
+		struct msghdr msg = {
+			(void*)&nladdr, sizeof(nladdr),
+			&iov,   1,
+			NULL,   0,
+			0
+		};
+
+		status = recvmsg(fd, &msg, 0);
+		if (!status) {
+			close(fd);
+			return -1;
+		}
+
+		h = (struct nlmsghdr *)rcvbuf;
+		if (h->nlmsg_type == NLMSG_DONE)
+			break;
+
+		if (h->nlmsg_type == NLMSG_ERROR) {
+			close(fd);
+			return -1;
+		}
+
+		while (NLMSG_OK(h, status)) {
+			if (h->nlmsg_type == RTM_NEWADDR) {
+				struct ifaddrmsg *msg = NLMSG_DATA(h);
+				struct rtattr *rta = (struct rtattr *)(msg+1);
+				struct totem_ip_address ipaddr;
+				unsigned char *data = (unsigned char *)(rta+1);
+
+				ipaddr.family = bindnet->family;
+				memcpy(ipaddr.addr, data, TOTEMIP_ADDRLEN);
+				if (totemip_equal(&ipaddr, bindnet)) {
+
+					/* Found it - check I/F is UP */
+					struct ifreq ifr;
+					int ioctl_fd; /* Can't do ioctls on netlink FDs */
+
+					ioctl_fd = socket(AF_INET, SOCK_STREAM, 0);
+					if (ioctl_fd < 0) {
+						close(fd);
+						return -1;
+					}
+					memset(&ifr, 0, sizeof(ifr));
+					ifr.ifr_ifindex = msg->ifa_index;
+
+					/* SIOCGIFFLAGS needs an interface name */
+					status = ioctl(ioctl_fd, SIOCGIFNAME, &ifr);
+					status = ioctl(ioctl_fd, SIOCGIFFLAGS, &ifr);
+					if (status) {
+						close(ioctl_fd);
+						close(fd);
+						return -1;
+					}
+
+					if (ifr.ifr_flags & IFF_UP)
+						*interface_up = 1;
+
+					*interface_num = msg->ifa_index;
+					close(ioctl_fd);
+					goto finished;
+				}
+			}
+
+			h = NLMSG_NEXT(h, status);
+		}
+	}
+finished:
+	totemip_copy (boundto, bindnet);
+	close(fd);
+	return 0;
+}

+ 73 - 0
exec/totemip.h

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2005 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@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.
+ */
+
+/* IPv4/6 abstraction */
+
+#ifndef TOTEMIP_H_DEFINED
+#define TOTEMIP_H_DEFINED
+
+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
+
+/* These are the things that get passed around */
+struct totem_ip_address
+{
+	unsigned int   nodeid;
+	unsigned short family;
+	unsigned char  addr[TOTEMIP_ADDRLEN];
+} __attribute__((packed));
+
+
+extern int totemip_equal(struct totem_ip_address *addr1, struct totem_ip_address *addr2);
+extern int totemip_compare(const void *a, const void *b);
+extern void totemip_copy(struct totem_ip_address *addr1, struct totem_ip_address *addr2);
+int totemip_localhost(int family, struct totem_ip_address *localhost);
+extern int totemip_localhost_check(struct totem_ip_address *addr);
+extern const char *totemip_print(struct totem_ip_address *addr);
+extern int totemip_sockaddr_to_totemip_convert(struct sockaddr_storage *saddr, struct totem_ip_address *ip_addr);
+extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
+					       uint16_t port, struct sockaddr_storage *saddr, int *addrlen);
+extern int totemip_parse(struct totem_ip_address *totemip, char *addr);
+extern int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num);
+
+/* These two simulate a zero in_addr by clearing the family field */
+static inline void totemip_zero_set(struct totem_ip_address *addr)
+{
+	addr->family = 0;
+}
+static inline int totemip_zero_check(struct totem_ip_address *addr)
+{
+	return (addr->family == 0);
+}
+
+#endif

+ 12 - 12
exec/totemmrp.c

@@ -63,20 +63,20 @@
 totemsrp_handle totemsrp_handle_in;
 
 void (*pg_deliver_fn) (
-	struct in_addr source_addr,
+	struct totem_ip_address *source_addr,
 	struct iovec *iovec,
 	int iov_len,
 	int endian_conversion_required) = 0;
 
 void (*pg_confchg_fn) (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id) = 0;
 
 void totemmrp_deliver_fn (
-	struct in_addr source_addr,
+	struct totem_ip_address *source_addr,
 	struct iovec *iovec,
 	int iov_len,
 	int endian_conversion_required)
@@ -86,9 +86,9 @@ void totemmrp_deliver_fn (
 
 void totemmrp_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 	pg_confchg_fn (configuration_type,
@@ -107,15 +107,15 @@ int totemmrp_initialize (
 	struct totem_config *totem_config,
 
 	void (*deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required),
 	void (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id))
 {
 	int result;

+ 4 - 6
exec/totemmrp.h

@@ -63,15 +63,15 @@ int totemmrp_initialize (
 	struct totem_config *totem_config,
 
 	void (*deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required),
 	void (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id));
 
 int totemmrp_finalize (void);
@@ -101,6 +101,4 @@ void totemmrp_callback_token_destroy (
 
 void totemmrp_new_msg_signal (void);
 
-extern struct sockaddr_in config_mcast_addr;
-
 #endif /* TOTEMMRP_H_DEFINED */

+ 337 - 200
exec/totemnet.c

@@ -79,8 +79,6 @@
 #define BIND_STATE_REGULAR	1
 #define BIND_STATE_LOOPBACK	2
 
-#define LOCALHOST_IP inet_addr("127.0.0.1")
-
 #define HMAC_HASH_SIZE 20
 struct security_header {
 	unsigned char hash_digest[HMAC_HASH_SIZE]; /* The hash *MUST* be first in the data structure */
@@ -94,7 +92,8 @@ struct totemnet_mcast_thread_state {
 };
 
 struct totemnet_socket {
-	int mcast;
+	int mcast_recv;
+	int mcast_send;
 	int token;
 };
 
@@ -121,13 +120,13 @@ struct totemnet_instance {
 
 	void (*totemnet_deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len);
 
 	void (*totemnet_iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in);
+		struct totem_ip_address *iface_address);
 
 	/*
 	 * Function and data used to log messages
@@ -156,9 +155,7 @@ struct totemnet_instance {
 
 	struct totemnet_socket totemnet_sockets;
 
-	struct sockaddr_in sockaddr_in_mcast;
-
-	struct in_addr in_addr_mcast;
+	struct totem_ip_address mcast_address;
 
 	int stats_sent;
 
@@ -172,7 +169,7 @@ struct totemnet_instance {
 
 	struct timeval stats_tv_start;
 
-	struct sockaddr_in my_id;
+	struct totem_ip_address my_id;
 
 	int firstrun;
 
@@ -200,23 +197,23 @@ static struct saHandleDatabase totemnet_instance_database = {
 	.handleInstanceDestructor	= 0
 };
 
-static int loopback_determine (struct sockaddr_in *bound_to);
+static int loopback_determine (int family, struct totem_ip_address *bound_to);
 static void netif_down_check (struct totemnet_instance *instance);
 
 static int totemnet_build_sockets (
 	struct totemnet_instance *instance,
-	struct sockaddr_in *sockaddr_mcast,
-	struct sockaddr_in *sockaddr_bindnet,
+	struct totem_ip_address *bindnet_address,
+	struct totem_ip_address *mcastaddress,
 	struct totemnet_socket *sockets,
-	struct sockaddr_in *bound_to,
+	struct totem_ip_address *bound_to,
 	int *interface_up);
 
 static int totemnet_build_sockets_loopback (
 	struct totemnet_instance *instance,
-	struct sockaddr_in *sockaddr_mcast,
-	struct sockaddr_in *sockaddr_bindnet,
+	struct totem_ip_address *mcast_address,
+	struct totem_ip_address *bindnet_address,
 	struct totemnet_socket *sockets,
-	struct sockaddr_in *bound_to);
+	struct totem_ip_address *bound_to);
 
 static void totemnet_instance_initialize (struct totemnet_instance *instance)
 {
@@ -389,7 +386,9 @@ void totemnet_iovec_send (
 	unsigned char encrypt_data[FRAME_SIZE_MAX];
 	struct iovec iovec_encrypt[20];
 	struct iovec *iovec_sendmsg;
+	struct sockaddr_storage sockaddr;
 	int iov_len;
+	int addrlen;
 
 	if (instance->totem_config->secauth == 1) {
 
@@ -421,8 +420,10 @@ void totemnet_iovec_send (
 	/*
 	 * Build multicast message
 	 */
-	msg_mcast.msg_name = &instance->sockaddr_in_mcast;
-	msg_mcast.msg_namelen = sizeof (struct sockaddr_in);
+	totemip_totemip_to_sockaddr_convert(&instance->mcast_address,
+		instance->totem_config->ip_port, &sockaddr, &addrlen);
+	msg_mcast.msg_name = &sockaddr;
+	msg_mcast.msg_namelen = addrlen;
 	msg_mcast.msg_iov = iovec_sendmsg;
 	msg_mcast.msg_iovlen = iov_len;
 	msg_mcast.msg_control = 0;
@@ -430,19 +431,19 @@ void totemnet_iovec_send (
 	msg_mcast.msg_flags = 0;
 
 	/*
-	 * Transmit token or multicast message
+	 * Transmit multicast message
 	 * An error here is recovered by totemnet
 	 */
-	res = sendmsg (instance->totemnet_sockets.mcast, &msg_mcast, MSG_NOSIGNAL | MSG_DONTWAIT);
+	res = sendmsg (instance->totemnet_sockets.mcast_send, &msg_mcast,
+		MSG_NOSIGNAL | MSG_DONTWAIT);
 }
 
 void totemnet_msg_send (
 	struct totemnet_instance *instance,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	int msg_len)
 {
-	struct sockaddr_in next_addr;
 	struct msghdr msg_mcast;
 	int res = 0;
 	int buf_len;
@@ -450,6 +451,8 @@ void totemnet_msg_send (
 	unsigned char encrypt_data[FRAME_SIZE_MAX];
 	struct iovec iovec[2];
 	struct iovec iovec_sendmsg;
+	struct sockaddr_storage sockaddr;
+	int addrlen;
 	int fd;
 
 	if (instance->totem_config->secauth == 1) {
@@ -484,21 +487,18 @@ void totemnet_msg_send (
 		/*
 		 * system_to is non-zero, so its a token send operation
 		 */
-		next_addr.sin_addr.s_addr = system_to->s_addr;
-		next_addr.sin_port = instance->sockaddr_in_mcast.sin_port;
-		next_addr.sin_family = AF_INET;
-
+		totemip_totemip_to_sockaddr_convert(system_to, instance->totem_config->ip_port, &sockaddr, &addrlen);
 		fd = instance->totemnet_sockets.token;
-		msg_mcast.msg_name = &next_addr;
 	} else {
 		/*
 		 * system_to is zero, so its a mcast send operation
 		 */
-		fd = instance->totemnet_sockets.mcast;
-		msg_mcast.msg_name = &instance->sockaddr_in_mcast;
+		totemip_totemip_to_sockaddr_convert(&instance->mcast_address, instance->totem_config->ip_port, &sockaddr, &addrlen);
+		fd = instance->totemnet_sockets.mcast_send;
 	}
 
-	msg_mcast.msg_namelen = sizeof (struct sockaddr_in);
+	msg_mcast.msg_name = &sockaddr;
+	msg_mcast.msg_namelen = addrlen;
 	msg_mcast.msg_iov = &iovec_sendmsg;
 	msg_mcast.msg_iovlen = 1;
 	msg_mcast.msg_control = 0;
@@ -510,7 +510,6 @@ void totemnet_msg_send (
 	 * An error here is recovered by totemnet
 	 */
 	res = sendmsg (fd, &msg_mcast, MSG_NOSIGNAL | MSG_DONTWAIT);
-//printf ("sent %d bytes\n", res);
 }
 
 static void totemnet_mcast_thread_state_constructor (
@@ -538,7 +537,9 @@ static void totemnet_mcast_worker_fn (void *thread_state, void *work_item_in)
 	int buf_len;
 	struct iovec iovec_encrypted;
 	struct iovec *iovec_sendmsg;
+	struct sockaddr_storage sockaddr;
 	unsigned int iovs;
+	int addrlen;
 
 	if (instance->totem_config->secauth == 1) {
 		memmove (&work_item->iovec[1], &work_item->iovec[0],
@@ -564,8 +565,11 @@ static void totemnet_mcast_worker_fn (void *thread_state, void *work_item_in)
 		iovs = work_item->iov_len;
 	}
 
-	msg_mcast.msg_name = &instance->sockaddr_in_mcast;
-	msg_mcast.msg_namelen = sizeof (struct sockaddr_in);
+	totemip_totemip_to_sockaddr_convert(&instance->mcast_address,
+		instance->totem_config->ip_port, &sockaddr, &addrlen);
+
+	msg_mcast.msg_name = &sockaddr;
+	msg_mcast.msg_namelen = addrlen;
 	msg_mcast.msg_iov = iovec_sendmsg;
 	msg_mcast.msg_iovlen = iovs;
 	msg_mcast.msg_control = 0;
@@ -573,17 +577,16 @@ static void totemnet_mcast_worker_fn (void *thread_state, void *work_item_in)
 	msg_mcast.msg_flags = 0;
 
 	/*
-	 * Transmit token or multicast message
+	 * Transmit multicast message
 	 * An error here is recovered by totemnet
 	 */
-	res = sendmsg (instance->totemnet_sockets.mcast, &msg_mcast, MSG_NOSIGNAL | MSG_DONTWAIT);
-
+	res = sendmsg (instance->totemnet_sockets.mcast_send, &msg_mcast,
+		MSG_NOSIGNAL | MSG_DONTWAIT);
 	if (res > 0) {
 		instance->stats_sent += res;
 	}
 }
 
-
 int totemnet_finalize (
 	totemnet_handle handle)
 {
@@ -621,7 +624,8 @@ static int net_deliver_fn (
 	struct msghdr msg_recv;
 	struct iovec *iovec;
 	struct security_header *security_header;
-	struct sockaddr_in system_from;
+	struct sockaddr_storage system_from;
+	struct totem_ip_address from_address;
 	int bytes_received;
 	int res = 0;
 	unsigned char *msg_offset;
@@ -639,7 +643,7 @@ static int net_deliver_fn (
 	 * Receive datagram
 	 */
 	msg_recv.msg_name = &system_from;
-	msg_recv.msg_namelen = sizeof (struct sockaddr_in);
+	msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
 	msg_recv.msg_iov = iovec;
 	msg_recv.msg_iovlen = 1;
 	msg_recv.msg_control = 0;
@@ -659,6 +663,7 @@ static int net_deliver_fn (
 		instance->totemnet_log_printf (instance->totemnet_log_level_security, "Received message is too short...  ignoring %d.\n", bytes_received);
 		return (0);
 	}
+	totemip_sockaddr_to_totemip_convert(&system_from, &from_address);
 
 	security_header = (struct security_header *)iovec->iov_base;
 
@@ -687,7 +692,7 @@ static int net_deliver_fn (
 	 */
 	instance->totemnet_deliver_fn (
 		instance->context,
-		&system_from.sin_addr,
+		&from_address,
 		msg_offset,
 		size_delv);
 		
@@ -697,73 +702,34 @@ static int net_deliver_fn (
 
 static int netif_determine (
 	struct totemnet_instance *instance,
-	struct sockaddr_in *bindnet,
-	struct sockaddr_in *bound_to,
-	int *interface_up)
+	struct totem_ip_address *bindnet,
+	struct totem_ip_address *bound_to,
+	int *interface_up,
+	int *interface_num)
 {
-	struct sockaddr_in *sockaddr_in;
-	int id_fd;
-	struct ifconf ifc;
-	int numreqs = 0;
 	int res;
-	int i;
-	in_addr_t mask_addr;
 
-	*interface_up = 0;
+	res = totemip_iface_check (bindnet, bound_to,
+		interface_up, interface_num);
 
 	/*
-	 * Generate list of local interfaces in ifc.ifc_req structure
+	 * If the desired binding is to an IPV4 network and nodeid isn't
+	 * specified, retrieve the node id from this_ip network address
+	 *
+	 * IPV6 networks must have a node ID specified since the node id
+	 * field is only 32 bits.
 	 */
-	id_fd = socket (AF_INET, SOCK_STREAM, 0);
-	ifc.ifc_buf = 0;
-	do {
-		numreqs += 32;
-		ifc.ifc_len = sizeof (struct ifreq) * numreqs;
-		ifc.ifc_buf = (void *)realloc(ifc.ifc_buf, ifc.ifc_len);
-		res = ioctl (id_fd, SIOCGIFCONF, &ifc);
-		if (res < 0) {
-			close (id_fd);
-			return -1;
-		}
-	} while (ifc.ifc_len == sizeof (struct ifreq) * numreqs);
-	res = -1;
-
-	/*
-	 * Find interface address to bind to
-	 */
-	for (i = 0; i < ifc.ifc_len / sizeof (struct ifreq); i++) {
-		sockaddr_in = (struct sockaddr_in *)&ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr;
-		mask_addr = inet_addr ("255.255.255.0");
-
-		if ((sockaddr_in->sin_family == AF_INET) &&
-			(sockaddr_in->sin_addr.s_addr & mask_addr) ==
-			(bindnet->sin_addr.s_addr & mask_addr)) {
-
-			bound_to->sin_addr.s_addr = sockaddr_in->sin_addr.s_addr;
-			res = i;
-
-			if (ioctl(id_fd, SIOCGIFFLAGS, &ifc.ifc_ifcu.ifcu_req[i]) < 0) {
-				printf ("couldn't do ioctl\n");
-			}
-
-			*interface_up = ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_flags & IFF_UP;
-			break; /* for */
-		}
+	if (bound_to->family == AF_INET && bound_to->nodeid == 0) {
+		memcpy (&bound_to->nodeid, bound_to->addr, sizeof (int));
 	}
-	free (ifc.ifc_buf);
-	close (id_fd);
-	
+
 	return (res);
 }
+	
 
-static int loopback_determine (struct sockaddr_in *bound_to)
+static int loopback_determine (int family, struct totem_ip_address *bound_to)
 {
-
-	bound_to->sin_addr.s_addr = LOCALHOST_IP;
-	if (&bound_to->sin_addr.s_addr == 0) {
-		return -1;
-	}
-	return 1;
+	return totemip_localhost(family, bound_to);
 }
 
 
@@ -777,6 +743,7 @@ static void timer_function_netif_check_timeout (
 	struct totemnet_instance *instance = (struct totemnet_instance *)data;
 	int res;
 	int interface_up;
+	int interface_num;
 
 	/*
 	* Build sockets for every interface
@@ -784,23 +751,28 @@ static void timer_function_netif_check_timeout (
 	netif_determine (instance,
 		&instance->totemnet_interface->bindnet,
 		&instance->totemnet_interface->boundto,
-		&interface_up);
+		&interface_up, &interface_num);
 
-	if (instance->totemnet_sockets.mcast > 0) {
-		close (instance->totemnet_sockets.mcast);
+	if (instance->totemnet_sockets.mcast_recv > 0) {
+		close (instance->totemnet_sockets.mcast_recv);
 	 	poll_dispatch_delete (instance->totemnet_poll_handle,
-		instance->totemnet_sockets.mcast);
+			instance->totemnet_sockets.mcast_recv);
+	}
+	if (instance->totemnet_sockets.mcast_send > 0) {
+		close (instance->totemnet_sockets.mcast_send);
+	 	poll_dispatch_delete (instance->totemnet_poll_handle,
+			instance->totemnet_sockets.mcast_send);
 	}
 	if (instance->totemnet_sockets.token > 0) {
 		close (instance->totemnet_sockets.token);
 		poll_dispatch_delete (instance->totemnet_poll_handle,
-		instance->totemnet_sockets.token);
+			instance->totemnet_sockets.token);
 	}
 
 	if (!interface_up) {
 		instance->netif_bind_state = BIND_STATE_LOOPBACK;
 		res = totemnet_build_sockets_loopback(instance,
-			&instance->sockaddr_in_mcast,
+			&instance->mcast_address,
 			&instance->totemnet_interface->bindnet,
 			&instance->totemnet_sockets,
 			&instance->totemnet_interface->boundto);
@@ -815,10 +787,8 @@ static void timer_function_netif_check_timeout (
 		/*
 		* Create and bind the multicast and unicast sockets
 		*/
-		memcpy (&instance->sockaddr_in_mcast.sin_addr,
-			&instance->in_addr_mcast, sizeof (struct in_addr));
 		res = totemnet_build_sockets (instance,
-			&instance->sockaddr_in_mcast,
+			&instance->mcast_address,
 			&instance->totemnet_interface->bindnet,
 			&instance->totemnet_sockets,
 			&instance->totemnet_interface->boundto,
@@ -826,7 +796,7 @@ static void timer_function_netif_check_timeout (
 
 		poll_dispatch_add (
 			instance->totemnet_poll_handle,
-			instance->totemnet_sockets.mcast,
+			instance->totemnet_sockets.mcast_recv,
 			POLLIN, instance, net_deliver_fn, UINT_MAX);
 
 		poll_dispatch_add (
@@ -835,8 +805,7 @@ static void timer_function_netif_check_timeout (
 			POLLIN, instance, net_deliver_fn, UINT_MAX);
 	}
 
-	memcpy (&instance->my_id, &instance->totemnet_interface->boundto,
-		sizeof (struct sockaddr_in));	
+	totemip_copy (&instance->my_id, &instance->totemnet_interface->boundto);
 
 	/*
 	* This stuff depends on totemnet_build_sockets
@@ -845,7 +814,7 @@ static void timer_function_netif_check_timeout (
 		if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
 			instance->totemnet_log_printf (instance->totemnet_log_level_notice,
 				" The network interface [%s] is now up.\n",
-				inet_ntoa (instance->totemnet_interface->boundto.sin_addr));
+				totemip_print (&instance->totemnet_interface->boundto));
 			instance->netif_state_report = NETIF_STATE_REPORT_DOWN;
 			instance->totemnet_iface_change_fn (instance->context, &instance->my_id);
 		}
@@ -854,15 +823,17 @@ static void timer_function_netif_check_timeout (
 		 * If this is a single processor, detect downs which may not 
 		 * be detected by token loss when the interface is downed
 		 */
-		/*
+		
+/*
 		if (instance->my_memb_entries <= 1) {
 			poll_timer_add (instance->totemnet_poll_handle,
-				instance->timeout_downcheck,
+				instance->totem_config->downcheck_timeout,
 				(void *)instance,
 				timer_function_netif_check_timeout,
 				&instance->timer_netif_check_timeout);
 		}
-		*/
+*/
+		
 	} else {		
 		if (instance->netif_state_report & NETIF_STATE_REPORT_DOWN) {
 			instance->totemnet_log_printf (instance->totemnet_log_level_notice,
@@ -874,11 +845,13 @@ static void timer_function_netif_check_timeout (
 		/*
 		 * Add a timer to retry building interfaces and request memb_gather_enter
 		 */
+/*
 		poll_timer_add (instance->totemnet_poll_handle,
 			instance->totem_config->downcheck_timeout,
 			(void *)instance,
 			timer_function_netif_check_timeout,
 			&instance->timer_netif_check_timeout);
+*/
 	}
 }
 
@@ -892,15 +865,16 @@ static void netif_down_check (struct totemnet_instance *instance)
 	timer_function_netif_check_timeout (instance);
 }
 
-	struct sockaddr_in sockaddr_in_test;
 static int totemnet_build_sockets_loopback (
 	struct totemnet_instance *instance,
-	struct sockaddr_in *sockaddr_mcast,
-	struct sockaddr_in *sockaddr_bindnet,
+	struct totem_ip_address *mcast_addr,
+	struct totem_ip_address *bindnet_addr,
 	struct totemnet_socket *sockets,
-	struct sockaddr_in *bound_to)
+	struct totem_ip_address *bound_to)
 {
 	struct ip_mreq mreq;
+	struct sockaddr_storage sockaddr;
+	int addrlen;
 	int res;
 
 	memset (&mreq, 0, sizeof (struct ip_mreq));
@@ -908,21 +882,18 @@ static int totemnet_build_sockets_loopback (
 	/*
 	 * Determine the ip address bound to and the interface name
 	 */
-	res = loopback_determine (bound_to);
+	res = loopback_determine (mcast_addr->family, bound_to);
 
 	if (res == -1) {
 		return (-1);
 	}
 
-	/* TODO this should be somewhere else */
-	instance->my_id.sin_addr.s_addr = bound_to->sin_addr.s_addr;
-	instance->my_id.sin_family = AF_INET;
-	instance->my_id.sin_port = sockaddr_mcast->sin_port;
+	totemip_copy(&instance->my_id, bound_to);
 
 	 /*
 	 * Setup unicast socket
 	 */
-	sockets->token = socket (AF_INET, SOCK_DGRAM, 0);
+	sockets->token = socket (bound_to->family, SOCK_DGRAM, 0);
 	if (sockets->token == -1) {
 		perror ("socket2");
 		return (-1);
@@ -932,70 +903,94 @@ static int totemnet_build_sockets_loopback (
 	 * Bind to unicast socket used for token send/receives	
 	 * This has the side effect of binding to the correct interface
 	 */
-	sockaddr_in_test.sin_addr.s_addr = bound_to->sin_addr.s_addr;
-	sockaddr_in_test.sin_family = AF_INET;
-	sockaddr_in_test.sin_port = sockaddr_mcast->sin_port;
-
-	res = bind (sockets->token, (struct sockaddr *)&sockaddr_in_test,
-			sizeof (struct sockaddr_in));
+	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_config->ip_port, &sockaddr, &addrlen);
+	res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
 	if (res == -1) {
 		perror ("bind2 failed");
 		return (-1);
 	}
 
-	memcpy(&instance->sockaddr_in_mcast, &sockaddr_in_test, sizeof(struct sockaddr_in));
-	sockets->mcast = sockets->token;
+	sockets->mcast_send = sockets->token;
+	sockets->mcast_recv = sockets->token;
 
 	return (0);
 }
+/* Set the socket priority to INTERACTIVE to ensure
+   that our messages don't get queued behind anything else */
+static void totemnet_traffic_control_set(struct totemnet_instance *instance, int sock)
+{
+    int prio = 6; /* TC_PRIO_INTERACTIVE */
 
+    if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int)))
+		instance->totemnet_log_printf (instance->totemnet_log_level_warning, "Could not set traffic priority. (%s)\n", strerror (errno));
+}
 
-static int totemnet_build_sockets (
+static int totemnet_build_sockets_ipv4 (
 	struct totemnet_instance *instance,
-	struct sockaddr_in *sockaddr_mcast,
-	struct sockaddr_in *sockaddr_bindnet,
+	struct totem_ip_address *mcast_address,
+	struct totem_ip_address *bindnet_address,
 	struct totemnet_socket *sockets,
-	struct sockaddr_in *bound_to,
+	struct totem_ip_address *bound_to,
 	int *interface_up)
 {
 	struct ip_mreq mreq;
-	struct sockaddr_in sockaddr_in_test;
-	char flag;
-	int res;
+	struct sockaddr_storage bound_ss;
+	struct sockaddr_in *bound_sin = (struct sockaddr_in *)&bound_ss;
+	struct sockaddr_storage mcast_ss;
+	struct sockaddr_in *mcast_sin = (struct sockaddr_in *)&mcast_ss;
+	struct sockaddr_storage sockaddr;
 	unsigned int sendbuf_size;
 	unsigned int recvbuf_size;
 	unsigned int optlen = sizeof (sendbuf_size);
-	
-	memset (&mreq, 0, sizeof (struct ip_mreq));
+	int flag;
+	int addrlen;
+	int res;
 
 	/*
-	 * Determine the ip address bound to and the interface name
+	 * Create multicast socket
 	 */
-	res = netif_determine (instance,
-		sockaddr_bindnet,
-		bound_to,
-		interface_up);
+	sockets->mcast_send = socket (AF_INET, SOCK_DGRAM, 0);
+	if (sockets->mcast_send == -1) {
+		perror ("socket");
+		return (-1);
+	}
 
+	/*
+	 * Bind to multicast socket used for multicast send/receives
+	 */
+	totemip_totemip_to_sockaddr_convert(mcast_address, instance->totem_config->ip_port, &sockaddr, &addrlen);
+	res = bind (sockets->mcast_send, (struct sockaddr *)&sockaddr, addrlen);
 	if (res == -1) {
+		perror ("bind failed");
 		return (-1);
 	}
 
-	/* TODO this should be somewhere else */
-	instance->my_id.sin_addr.s_addr = bound_to->sin_addr.s_addr;
-	instance->my_id.sin_family = AF_INET;
-	instance->my_id.sin_port = sockaddr_mcast->sin_port;
+	/*
+	 * Setup unicast socket
+	 */
+	sockets->token = socket (AF_INET, SOCK_DGRAM, 0);
+	if (sockets->token == -1) {
+		perror ("socket2");
+		return (-1);
+	}
 
 	/*
-	 * Create multicast socket
+	 * Bind to unicast socket used for token send/receives
+	 * This has the side effect of binding to the correct interface
 	 */
-	sockets->mcast = socket (AF_INET, SOCK_DGRAM, 0);
-	if (sockets->mcast == -1) {
-		perror ("socket");
+	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_config->ip_port, &sockaddr, &addrlen);
+	res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
+	if (res == -1) {
+		perror ("bind2 failed");
 		return (-1);
 	}
 
-	if (setsockopt (sockets->mcast, SOL_IP, IP_MULTICAST_IF,
-		&bound_to->sin_addr, sizeof (struct in_addr)) < 0) {
+	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_config->ip_port, &bound_ss, &addrlen);
+	totemip_totemip_to_sockaddr_convert(mcast_address, instance->totem_config->ip_port, &mcast_ss, &addrlen);
+	memset (&mreq, 0, sizeof (struct ip_mreq));
+
+	if (setsockopt (sockets->mcast_send, SOL_IP, IP_MULTICAST_IF,
+		&bound_sin->sin_addr, sizeof (struct in_addr)) < 0) {
 
 		instance->totemnet_log_printf (instance->totemnet_log_level_warning, "Could not bind to device for multicast, group messaging may not work properly. (%s)\n", strerror (errno));
 	}
@@ -1005,38 +1000,118 @@ static int totemnet_build_sockets (
 	/*
 	 * Set buffer sizes to avoid overruns
 	 */
-	res = setsockopt (sockets->mcast, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
-	res = setsockopt (sockets->mcast, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
+	res = setsockopt (sockets->mcast_send, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
+	res = setsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
 
-	res = getsockopt (sockets->mcast, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
+	res = getsockopt (sockets->mcast_send, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
 	if (res == 0) {
 		instance->totemnet_log_printf (instance->totemnet_log_level_notice,
-			"Multicast socket recv buffer size (%d bytes).\n", recvbuf_size);
+			"Multicast socket send buffer size (%d bytes).\n", recvbuf_size);
 	}
 
-	res = getsockopt (sockets->mcast, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
+	res = getsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size,
+		&optlen);
 	if (res == 0) {
 		instance->totemnet_log_printf (instance->totemnet_log_level_notice,
 			"Multicast socket send buffer size (%d bytes).\n", sendbuf_size);
 	}
 
 	/*
-	 * Bind to multicast socket used for multicast send/receives
+	 * Join group membership
+	 */
+	mreq.imr_multiaddr.s_addr = mcast_sin->sin_addr.s_addr;
+	mreq.imr_interface.s_addr = bound_sin->sin_addr.s_addr;
+
+	res = setsockopt (sockets->mcast_send, SOL_IP, IP_ADD_MEMBERSHIP,
+		&mreq, sizeof (mreq));
+	if (res == -1) {
+		perror ("join ipv4 multicast group failed");
+		return (-1);
+	}
+
+	/*
+	 * Turn on multicast loopback
 	 */
-	sockaddr_in_test.sin_family = AF_INET;
-	sockaddr_in_test.sin_addr.s_addr = sockaddr_mcast->sin_addr.s_addr;
-	sockaddr_in_test.sin_port = sockaddr_mcast->sin_port;
-	res = bind (sockets->mcast, (struct sockaddr *)&sockaddr_in_test,
-		sizeof (struct sockaddr_in));
+	flag = 1;
+	res = setsockopt (sockets->mcast_send, IPPROTO_IP, IP_MULTICAST_LOOP,
+		&flag, sizeof (flag));
+	if (res == -1) {
+		perror ("turn off loopback");
+		return (-1);
+	}
+
+	/*
+	 * ipv4 binds to a network address, not a network interface like
+	 * ipv6.  So it is acceptable to utilize the same file descriptor
+	 * for both send and receive since outgoing packets will be
+	 * set with the correct source address
+	 */
+	sockets->mcast_recv = sockets->mcast_send;
+	return (0);
+}
+
+static int totemnet_build_sockets_ipv6 (
+	struct totemnet_instance *instance,
+	struct totem_ip_address *mcast_address,
+	struct totem_ip_address *bindnet_address,
+	struct totemnet_socket *sockets,
+	struct totem_ip_address *bound_to,
+	int *interface_up,
+	int interface_num)
+{
+	struct sockaddr_storage sockaddr;
+	struct ipv6_mreq mreq;
+	struct sockaddr_storage mcast_ss;
+	struct sockaddr_in6 *mcast_sin = (struct sockaddr_in6 *)&mcast_ss;
+	unsigned int sendbuf_size;
+        unsigned int recvbuf_size;
+        unsigned int optlen = sizeof (sendbuf_size);
+	int addrlen;
+	int res;
+	int flag;
+
+	/*
+	 * Create multicast recv socket
+	 */
+	sockets->mcast_recv = socket (AF_INET6, SOCK_DGRAM, 0);
+	if (sockets->mcast_recv == -1) {
+		perror ("socket");
+		return (-1);
+	}
+
+	/*
+	 * Bind to multicast socket used for multicast receives
+	 */
+	totemip_totemip_to_sockaddr_convert(mcast_address,
+		instance->totem_config->ip_port, &sockaddr, &addrlen);
+
+	res = bind (sockets->mcast_recv, (struct sockaddr *)&sockaddr, addrlen);
 	if (res == -1) {
 		perror ("bind failed");
 		return (-1);
 	}
 
+	/*
+	 * Setup mcast send socket
+	 */
+	sockets->mcast_send = socket (AF_INET6, SOCK_DGRAM, 0);
+	if (sockets->mcast_send == -1) {
+		perror ("socket");
+		return (-1);
+	}
+
+	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_config->ip_port - 1,
+		&sockaddr, &addrlen);
+	res = bind (sockets->mcast_send, (struct sockaddr *)&sockaddr, addrlen);
+	if (res == -1) {
+		perror ("bind2 failed");
+		return (-1);
+	}
+
 	/*
 	 * Setup unicast socket
 	 */
-	sockets->token = socket (AF_INET, SOCK_DGRAM, 0);
+	sockets->token = socket (AF_INET6, SOCK_DGRAM, 0);
 	if (sockets->token == -1) {
 		perror ("socket2");
 		return (-1);
@@ -1046,49 +1121,118 @@ static int totemnet_build_sockets (
 	 * Bind to unicast socket used for token send/receives
 	 * This has the side effect of binding to the correct interface
 	 */
-	sockaddr_in_test.sin_family = AF_INET;
-	sockaddr_in_test.sin_addr.s_addr = bound_to->sin_addr.s_addr;
-	sockaddr_in_test.sin_port = sockaddr_mcast->sin_port;
-	res = bind (sockets->token, (struct sockaddr *)&sockaddr_in_test,
-		sizeof (struct sockaddr_in));
+	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_config->ip_port, &sockaddr, &addrlen);
+	res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
 	if (res == -1) {
 		perror ("bind2 failed");
 		return (-1);
 	}
 
-#ifdef CONFIG_USE_BROADCAST
-/* This config option doesn't work */
-{
-	int on = 1;
-	setsockopt (sockets->mcast, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof (on));
+        recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+        sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+        /*
+         * Set buffer sizes to avoid overruns
+         */
+        res = setsockopt (sockets->mcast_recv, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
+        res = setsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
+
+        res = getsockopt (sockets->mcast_recv, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
+        if (res == 0) {
+                instance->totemnet_log_printf (instance->totemnet_log_level_notice,
+                        "Receive multicast socket recv buffer size (%d bytes).\n", recvbuf_size);
 }
-#else
+
+        res = getsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
+        if (res == 0) {
+                instance->totemnet_log_printf (instance->totemnet_log_level_notice,
+                        "Transmit multicat socket send buffer size (%d bytes).\n", sendbuf_size);
+        }
+
 	/*
 	 * Join group membership on socket
 	 */
-	mreq.imr_multiaddr.s_addr = sockaddr_mcast->sin_addr.s_addr;
-	mreq.imr_interface.s_addr = bound_to->sin_addr.s_addr;
+	totemip_totemip_to_sockaddr_convert(mcast_address,
+		instance->totem_config->ip_port, &mcast_ss, &addrlen);
+	memset(&mreq, 0, sizeof(mreq));
+	memcpy(&mreq.ipv6mr_multiaddr, &mcast_sin->sin6_addr, sizeof(struct in6_addr));
+	mreq.ipv6mr_interface = interface_num;
 
-	res = setsockopt (sockets->mcast, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+	res = setsockopt (sockets->mcast_recv, SOL_IPV6, IPV6_ADD_MEMBERSHIP,
 		&mreq, sizeof (mreq));
 	if (res == -1) {
-		perror ("join multicast group failed");
+		perror ("join ipv6 multicast group failed");
 		return (-1);
 	}
 
-#endif
 	/*
 	 * Turn on multicast loopback
 	 */
 	flag = 1;
-	res = setsockopt (sockets->mcast, IPPROTO_IP, IP_MULTICAST_LOOP,
+	res = setsockopt (sockets->mcast_send, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
 		&flag, sizeof (flag));
 	if (res == -1) {
 		perror ("turn off loopback");
 		return (-1);
 	}
 
-	return (0);
+	flag = 255;
+	res = setsockopt (sockets->mcast_send, SOL_IPV6, IPV6_MULTICAST_HOPS,
+		&flag, sizeof (flag));
+	if (res == -1) {
+		perror ("setp mcast hops");
+		return (-1);
+	}
+
+	/*
+	 * Bind to a specific interface for multicast send and receive
+	 */
+	if (setsockopt (sockets->mcast_send, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+		&interface_num, sizeof (interface_num)) < 0) {
+	}
+
+	if (setsockopt (sockets->mcast_recv, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+		&interface_num, sizeof (interface_num)) < 0) {
+	}
+	return 0;
+}
+
+static int totemnet_build_sockets (
+	struct totemnet_instance *instance,
+	struct totem_ip_address *mcast_address,
+	struct totem_ip_address *bindnet_address,
+	struct totemnet_socket *sockets,
+	struct totem_ip_address *bound_to,
+	int *interface_up)
+{
+	int interface_num;
+	int res;
+
+	/*
+	 * Determine the ip address bound to and the interface name
+	 */
+	res = netif_determine (instance,
+		bindnet_address,
+		bound_to,
+                interface_up,
+		&interface_num);
+
+	if (res == -1) {
+		return (-1);
+	}
+
+	totemip_copy(&instance->my_id, bound_to);
+
+	if (mcast_address->family== AF_INET)
+		res = totemnet_build_sockets_ipv4 (instance, mcast_address,
+			bindnet_address, sockets, bound_to, interface_up);
+	else {
+		res = totemnet_build_sockets_ipv6 (instance, mcast_address,
+			bindnet_address, sockets, bound_to, interface_up, interface_num);
+}
+
+	/* We only send out of the token socket */
+	totemnet_traffic_control_set(instance, sockets->token);
+	return res;
 }
 	
 /*
@@ -1108,18 +1252,17 @@ int totemnet_initialize (
 
 	void (*deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len),
 
 	void (*iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in))
+		struct totem_ip_address *iface_address))
 {
 	SaAisErrorT error;
 	struct totemnet_instance *instance;
 
-	memset (&sockaddr_in_test, 0, sizeof (struct sockaddr_in));
 	error = saHandleCreate (&totemnet_instance_database,
 	sizeof (struct totemnet_instance), handle);
 	if (error != SA_OK) {
@@ -1134,7 +1277,6 @@ int totemnet_initialize (
 	totemnet_instance_initialize (instance);
 
 	instance->totem_config = totem_config;
-
 	/*
 	* Configure logging
 	*/
@@ -1145,12 +1287,6 @@ int totemnet_initialize (
 	instance->totemnet_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
 	instance->totemnet_log_printf = totem_config->totem_logging_configuration.log_printf;
 
-	memcpy (&instance->sockaddr_in_mcast, &totem_config->mcast_addr,
-		sizeof (struct sockaddr_in));
-
-	memcpy (&instance->in_addr_mcast, &totem_config->mcast_addr.sin_addr,
-		sizeof (struct in_addr));
-
 	/*
 	* Initialize random number generator for later use to generate salt
 	*/
@@ -1164,8 +1300,7 @@ int totemnet_initialize (
 	/*
 	* Initialize local variables for totemnet
 	*/
-	memcpy (&instance->sockaddr_in_mcast, &totem_config->mcast_addr, 
-	sizeof (struct sockaddr_in));
+	totemip_copy (&instance->mcast_address, &totem_config->mcast_addr);
 	memset (instance->iov_buffer, 0, FRAME_SIZE_MAX);
 
 	/*
@@ -1184,6 +1319,8 @@ int totemnet_initialize (
 	instance->totemnet_interface = &totem_config->interfaces[interface_no];
 	instance->totemnet_poll_handle = poll_handle;
 
+	instance->totemnet_interface->bindnet.nodeid = instance->totem_config->node_id;
+
 	instance->context = context;
 	instance->totemnet_deliver_fn = deliver_fn;
 
@@ -1246,11 +1383,11 @@ int totemnet_recv_flush (totemnet_handle handle)
 	instance->flushing = 1;
 
 	do {
-		ufd.fd = instance->totemnet_sockets.mcast;
+		ufd.fd = instance->totemnet_sockets.mcast_recv;
 		ufd.events = POLLIN;
 		nfds = poll (&ufd, 1, 0);
 		if (nfds == 1 && ufd.revents & POLLIN) {
-		net_deliver_fn (0, instance->totemnet_sockets.mcast,
+		net_deliver_fn (0, instance->totemnet_sockets.mcast_recv,
 			ufd.revents, instance, &prio);
 		}
 	} while (nfds == 1);
@@ -1286,7 +1423,7 @@ error_exit:
 
 int totemnet_token_send (
 	totemnet_handle handle,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	int msg_len)
 {
@@ -1324,7 +1461,7 @@ int totemnet_mcast_flush_send (
 		goto error_exit;
 	}
 	
-	totemnet_msg_send (instance, 0, msg, msg_len);
+	totemnet_msg_send (instance, NULL, msg, msg_len);
 
 	saHandleInstancePut (&totemnet_instance_database, handle);
 

+ 3 - 3
exec/totemnet.h

@@ -61,13 +61,13 @@ extern int totemnet_initialize (
 
 	void (*deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len),
 
 	void (*iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in));
+		struct totem_ip_address *iface_address));
 
 extern int totemnet_processor_count_set (
 	totemnet_handle handle,
@@ -75,7 +75,7 @@ extern int totemnet_processor_count_set (
 
 extern int totemnet_token_send (
 	totemnet_handle handle,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	int msg_len);
 

+ 21 - 20
exec/totempg.c

@@ -81,6 +81,7 @@
  *	
  */
 
+#include <netinet/in.h>
 #include "totempg.h"
 #include "totemsrp.h"
 #include "totemmrp.h"
@@ -89,7 +90,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include <netinet/in.h>
+
 
 #include "swab.h"
 
@@ -140,20 +141,20 @@ static int mcast_packed_msg_count = 0;
 struct totem_config *totempg_totem_config;
 
 static void (*app_deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required) = 0;
 
 static void (*app_confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id) = 0;
 
 struct assembly {
-	struct in_addr addr;
+	struct totem_ip_address addr;
 	unsigned char data[MESSAGE_SIZE_MAX];
 	int index;
 	unsigned char last_frag_num;
@@ -178,12 +179,12 @@ int fragment_continuation = 0;
 
 static struct iovec iov_delv;
 
-static struct assembly *find_assembly (struct in_addr addr)
+static struct assembly *find_assembly (struct totem_ip_address *addr)
 {
 	int i;
 
 	for (i = 0; i < assembly_list_entries; i++) {
-		if (addr.s_addr == assembly_list[i]->addr.s_addr) {
+		if (totemip_equal(addr, &assembly_list[i]->addr)) {
 			return (assembly_list[i]);
 		}
 	}
@@ -192,9 +193,9 @@ static struct assembly *find_assembly (struct in_addr addr)
 
 static void totempg_confchg_fn (
 	enum totem_configuration_type configuration_type,
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries,
+	struct totem_ip_address *member_list, int member_list_entries,
+	struct totem_ip_address *left_list, int left_list_entries,
+	struct totem_ip_address *joined_list, int joined_list_entries,
 	struct memb_ring_id *ring_id)
 {
 	int i;
@@ -208,7 +209,7 @@ static void totempg_confchg_fn (
 	 */
 	for (i = 0; i < left_list_entries; i++) {
 		for (j = 0; j < assembly_list_entries; j++) {
-			if (left_list[i].s_addr == assembly_list[j]->addr.s_addr) {
+			if (totemip_equal(&left_list[i], &assembly_list[j]->addr)) {
 				assembly_list[j]->index = 0;
 			}
 		}
@@ -220,7 +221,7 @@ static void totempg_confchg_fn (
 	for (i = 0; i < member_list_entries; i++) {
 		found = 0;
 		for (j = 0; j < assembly_list_entries; j++) {
-			if (member_list[i].s_addr == assembly_list[j]->addr.s_addr) {
+			if (totemip_equal(&member_list[i], &assembly_list[j]->addr)) {
 				found = 1; 
 				break;
 			}
@@ -229,8 +230,8 @@ static void totempg_confchg_fn (
 			assembly_list[assembly_list_entries] =
 				malloc (sizeof (struct assembly));
 			assert (assembly_list[assembly_list_entries]); // TODO
-			assembly_list[assembly_list_entries]->addr.s_addr = 
-				member_list[i].s_addr;
+			totemip_copy(&assembly_list[assembly_list_entries]->addr, 
+				     &member_list[i]);
 			assembly_list[assembly_list_entries]->index = 0;
 			assembly_list_entries += 1;
 		}
@@ -244,7 +245,7 @@ static void totempg_confchg_fn (
 }
 
 static void totempg_deliver_fn (
-	struct in_addr source_addr,
+	struct totem_ip_address *source_addr,
 	struct iovec *iovec,
 	int iov_len,
 	int endian_conversion_required)
@@ -462,16 +463,16 @@ int totempg_initialize (
 	struct totem_config *totem_config,
 
 	void (*deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required),
 
 	void (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id))
 {
 	int res;

+ 4 - 4
exec/totempg.h

@@ -57,16 +57,16 @@ int totempg_initialize (
 	struct totem_config *totem_config,
 
 	void (*deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required),
 
 	void (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id));
 
 void totempg_finalize (void);

+ 21 - 21
exec/totemrrp.c

@@ -91,7 +91,7 @@ struct rrp_algo {
 	void (*mcast_recv) (
 		struct totemrrp_instance *instance,
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		unsigned int msg_len);
 
@@ -109,14 +109,14 @@ struct rrp_algo {
 		struct totemrrp_instance *instance,
 		unsigned int interface_no,
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		unsigned int msg_len,
 		unsigned int token_seqid);
 
 	void (*token_send) (
 		struct totemrrp_instance *instance,
-		struct in_addr *system_to,
+		struct totem_ip_address *system_to,
 		void *msg,
 		unsigned int msg_len);
 };
@@ -132,13 +132,13 @@ struct totemrrp_instance {
 	
 	void (*totemrrp_deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len);
 
 	void (*totemrrp_iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in);
+		struct totem_ip_address *iface_addr);
 
 	void (*totemrrp_token_seqid_get) (
 		void *msg,
@@ -178,7 +178,7 @@ struct totemrrp_instance {
 void passive_mcast_recv (
 	struct totemrrp_instance *instance,
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len);
 
@@ -195,21 +195,21 @@ void passive_mcast_flush_send (
 void passive_token_recv (
 	struct totemrrp_instance *instance,
 	unsigned int interface_no,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len,
 	unsigned int token_seqid);
 
 void passive_token_send (
 	struct totemrrp_instance *instance,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	unsigned int msg_len);
 
 void active_mcast_recv (
 	struct totemrrp_instance *instance,
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len);
 
@@ -227,14 +227,14 @@ void active_token_recv (
 	struct totemrrp_instance *instance,
 	unsigned int interface_no,
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len,
 	unsigned int token_seqid);
 
 void active_token_send (
 	struct totemrrp_instance *instance,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	unsigned int msg_len);
 
@@ -365,7 +365,7 @@ error_exit:
 
 static void timer_function_active_token (void *context)
 {
-	struct active_instance *instance = (struct active_instance *)context;
+//	struct active_instance *instance = (struct active_instance *)context;
 }
 
 
@@ -389,7 +389,7 @@ void active_token_timer_cancel (struct active_instance *active_instance)
 void active_mcast_recv (
 	struct totemrrp_instance *instance,
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len)
 {
@@ -433,7 +433,7 @@ void active_token_recv (
 	struct totemrrp_instance *instance,
 	unsigned int interface_no,
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	unsigned int msg_len,
 	unsigned int token_seqid)
@@ -487,7 +487,7 @@ void active_token_recv (
 
 void active_token_send (
 	struct totemrrp_instance *instance,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	unsigned int msg_len)
 {
@@ -519,7 +519,7 @@ static void totemrrp_instance_initialize (struct totemrrp_instance *instance)
 
 void rrp_deliver_fn (
 	void *context,
-	struct in_addr *system_from,
+	struct totem_ip_address *system_from,
 	void *msg,
 	int msg_len)
 {
@@ -560,13 +560,13 @@ void rrp_deliver_fn (
 
 void rrp_iface_change_fn (
 	void *context,
-	struct sockaddr_in *iface_sockaddr_in)
+	struct totem_ip_address *iface_addr)
 {
 	struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
 
 	deliver_fn_context->instance->totemrrp_iface_change_fn (
 		deliver_fn_context->context,
-		iface_sockaddr_in);
+		iface_addr);
 }
 
 int totemrrp_finalize (
@@ -607,13 +607,13 @@ int totemrrp_initialize (
 
 	void (*deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len),
 
 	void (*iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in),
+		struct totem_ip_address *iface_addr),
 
 	void (*token_seqid_get) (
 		void *msg,
@@ -772,7 +772,7 @@ error_exit:
 
 int totemrrp_token_send (
 	totemrrp_handle handle,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	int msg_len)
 {

+ 3 - 3
exec/totemrrp.h

@@ -61,13 +61,13 @@ extern int totemrrp_initialize (
 
 	void (*deliver_fn) (
 		void *context,
-		struct in_addr *system_from,
+		struct totem_ip_address *system_from,
 		void *msg,
 		int msg_len),
 
 	void (*iface_change_fn) (
 		void *context,
-		struct sockaddr_in *iface_sockaddr_in),
+		struct totem_ip_address *iface_addr),
 
 	void (*token_seqid_get) (
 		void *msg,
@@ -80,7 +80,7 @@ extern int totemrrp_processor_count_set (
 
 extern int totemrrp_token_send (
 	totemrrp_handle handle,
-	struct in_addr *system_to,
+	struct totem_ip_address *system_to,
 	void *msg,
 	int msg_len);
 

Разница между файлами не показана из-за своего большого размера
+ 155 - 147
exec/totemsrp.c


+ 4 - 6
exec/totemsrp.h

@@ -58,15 +58,15 @@ int totemsrp_initialize (
 	struct totem_config *totem_config,
 
 	void (*deliver_fn) (
-		struct in_addr source_addr,
+		struct totem_ip_address *source_addr,
 		struct iovec *iovec,
 		int iov_len,
 		int endian_conversion_required),
 	void (*confchg_fn) (
 		enum totem_configuration_type configuration_type,
-		struct in_addr *member_list, int member_list_entries,
-		struct in_addr *left_list, int left_list_entries,
-		struct in_addr *joined_list, int joined_list_entries,
+		struct totem_ip_address *member_list, int member_list_entries,
+		struct totem_ip_address *left_list, int left_list_entries,
+		struct totem_ip_address *joined_list, int joined_list_entries,
 		struct memb_ring_id *ring_id));
 
 void totemsrp_finalize (totemsrp_handle handle);
@@ -99,8 +99,6 @@ void totemsrp_callback_token_destroy (
 
 int totemsrp_new_msg_signal (totemsrp_handle handle);
 
-extern struct sockaddr_in config_mcast_addr;
-
 extern void totemsrp_net_mtu_adjust (struct totem_config *totem_config);
 
 #endif /* TOTEMSRP_H_DEFINED */

+ 15 - 6
include/evs.h

@@ -67,19 +67,28 @@ typedef enum {
 	EVS_ERR_TOO_MANY_GROUPS=30
 } evs_error_t;
 
+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
+
+/* These are the things that get passed around */
+struct evs_address {
+	unsigned int nodeid;
+	unsigned short family;
+	unsigned char addr[TOTEMIP_ADDRLEN];
+};
+
 struct evs_group {
 	char key[32];
 };
 
 typedef void (*evs_deliver_fn_t) (
-	struct in_addr source_addr,
+	struct evs_address *source_addr,
 	void *msg,
 	int msg_len);
 
 typedef void (*evs_confchg_fn_t) (
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries);
+	struct evs_address *member_list, int member_list_entries,
+	struct evs_address *left_list, int left_list_entries,
+	struct evs_address *joined_list, int joined_list_entries);
 
 typedef struct {
 	evs_deliver_fn_t evs_deliver_fn;
@@ -162,8 +171,8 @@ evs_error_t evs_mcast_groups (
  */
 evs_error_t evs_membership_get (
 	evs_handle_t handle,
-	struct in_addr *local_addr,
-	struct in_addr *member_list,
+	struct evs_address *local_addr,
+	struct evs_address *member_list,
 	int *member_list_entries);
 
 #endif /* OPENAIS_EVS_H_DEFINED */

+ 5 - 5
include/ipc_evs.h

@@ -34,7 +34,7 @@
 #ifndef IPC_EVS_H_DEFINED
 #define IPC_EVS_H_DEFINED
 
-#include <netinet/in.h>
+//#include <netinet/in6.h>
 #include "saAis.h"
 #include "evs.h"
 #include "ipc_gen.h"
@@ -59,7 +59,7 @@ enum res_lib_evs_types {
 
 struct res_evs_deliver_callback {
 	struct res_header header;
-	struct in_addr source_addr;
+	struct evs_address evs_address;
 	int msglen;
 	char msg[0];
 };
@@ -69,9 +69,9 @@ struct res_evs_confchg_callback {
 	int member_list_entries;
 	int left_list_entries;
 	int joined_list_entries;
-	struct in_addr member_list[16];
-	struct in_addr left_list[16];
-	struct in_addr joined_list[16];
+	struct evs_address member_list[16];
+	struct evs_address left_list[16];
+	struct evs_address joined_list[16];
 };
 
 struct req_lib_evs_join {

+ 3 - 3
include/ipc_evt.h

@@ -252,7 +252,7 @@ struct res_evt_event_data {
  * MESSAGE_REQ_EXEC_EVT_RECOVERY_EVENTDATA	(4)
  *
  * led_head:				Request/Results head
- * led_in_addr:				address of node (4 only)
+ * led_addr:				address of node (4 only)
  * led_receive_time:		Time that the message was received (4 only)
  * led_svr_channel_handle:	Server channel handle (1 only)
  * led_lib_channel_handle:	Lib channel handle (2 only)
@@ -273,7 +273,7 @@ struct res_evt_event_data {
  */
 struct lib_event_data {
 	struct res_header		led_head;
-	struct in_addr			led_in_addr;
+	struct totem_ip_address	led_addr;
 	SaTimeT					led_receive_time;
 	uint32_t				led_svr_channel_handle;
 	SaEvtChannelHandleT		led_lib_channel_handle;
@@ -359,7 +359,7 @@ enum evt_chan_ops {
  * based on the highest ID seen by any of the members
  */
 struct evt_set_id {
-	struct in_addr	chc_addr;
+	unsigned int 	chc_nodeid;
 	uint64_t		chc_last_id;
 };
 

+ 2 - 1
include/ipc_gen.h

@@ -35,6 +35,7 @@
 #define IPC_GEN_H_DEFINED
 
 #include <netinet/in.h>
+#include "../exec/totemip.h"
 
 enum service_types {
 	EVS_SERVICE = 0,
@@ -111,7 +112,7 @@ struct res_lib_dispatch_init {
 };
 struct message_source {
 	struct conn_info *conn_info;
-	struct in_addr in_addr;
+	struct totem_ip_address addr;
 } __attribute__((packed));
 
 #endif /* IPC_GEN_H_DEFINED */

+ 3 - 3
lib/evs.c

@@ -292,7 +292,7 @@ evs_error_t evs_dispatch (
 		case MESSAGE_RES_EVS_DELIVER_CALLBACK:
 			res_evs_deliver_callback = (struct res_evs_deliver_callback *)&dispatch_data;
 			callbacks.evs_deliver_fn (
-				res_evs_deliver_callback->source_addr,
+				&res_evs_deliver_callback->evs_address,
 				&res_evs_deliver_callback->msg,
 				res_evs_deliver_callback->msglen);
 			break;
@@ -540,8 +540,8 @@ error_exit:
 
 evs_error_t evs_membership_get (
 	evs_handle_t handle,
-	struct in_addr *local_addr,
-	struct in_addr *member_list,
+	struct evs_address *local_addr,
+	struct evs_address *member_list,
 	int *member_list_entries)
 {
 	evs_error_t error;

+ 25 - 4
man/evs_initialize.3

@@ -61,14 +61,14 @@ is called.  The callback functions are described by the following type definitio
 .nf
 .ta 4n 20n 32n
 typedef void (*evs_deliver_fn_t) (
-        struct in_addr source_addr,
+        struct evs_address source_addr,
         void *msg,
         int msg_len);
 
 typedef void (*evs_confchg_fn_t) (
-        struct in_addr *member_list, int member_list_entries,
-        struct in_addr *left_list, int left_list_entries,
-        struct in_addr *joined_list, int joined_list_entries);
+        struct evs_address *member_list, int member_list_entries,
+        struct evs_address *left_list, int left_list_entries,
+        struct evs_address *joined_list, int joined_list_entries);
 .ta
 .fi
 .RE
@@ -101,6 +101,27 @@ is called.  If a delivery of a message occurs,
 .I evs_deliver_fn
 is called.
 
+The
+.I evs_address
+structure is defined 
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct evs_address {
+        unsigned int nodeid;
+        unsigned short family;
+        unsigned char addr[TOTEMIP_ADDRLEN];
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+where nodeid is a 32 bit unique node identifier, family is of the value AF_INET  for an IPV4 network, or AF_INET6 for an IPV6 network, and addr is a 32 bit address for an IPV4 network, or 128 bit address for an IPV6 network.
+
+
 .SH RETURN VALUE
 This call returns the EVS_OK value if successful, otherwise an error is returned.
 .PP

+ 3 - 2
man/evs_membership_get.3

@@ -37,14 +37,15 @@ evs_join \- Joins one or more groups in the EVS library
 .SH SYNOPSIS
 .B #include <openais/evs.h>
 .sp
-.BI "int evs_membership_get(evs_handle_t " handle ", struct in_addr *" local_addr ", struct in_addr *" member_list ", int *" member_list_entries ");
+.BI "int evs_membership_get(evs_handle_t " handle ", struct evs_address *" local_addr ", struct evs_address *" member_list ", int *" member_list_entries ");
 .SH DESCRIPTION
 The
 .B evs_membership_get
 function is used to determine the current processors in the configuration and also
 the local processor identifier.
 The argument
-.I handle is used to reference the evs instantiation.
+.I handle
+is used to reference the evs instantiation.
 The argument 
 .I local_addr
 will return the local address of the processor.

+ 18 - 0
man/openais.conf.5

@@ -71,6 +71,12 @@ Multiple bindnetaddr directives may be specified.  When multiple bindnetaddr
 directives are specified, the totem redundant ring protocol will use multiple
 interfaces to replicate the network traffic.
 
+This may also be an IPV6 address, in which case IPV6 networking will be used.
+In this case, the full address must be specified and there is no automatic
+selection of the network interface within a specific subnet as with IPv4.
+
+If IPv6 networking is used, the nodeid field must be specified.
+
 .TP
 mcastaddr
 This is the multicast address used by openais executive.  The default
@@ -78,12 +84,24 @@ should work for most networks, but the network administrator should be queried
 about a multicast address to use.  Avoid 224.x.x.x because this is a "config"
 multicast address.
 
+This may also be an IPV6 multicast address, in which case IPV6 networking
+will be used.  If IPv6 networking is used, the nodeid field must be specified.
+
 .TP
 mcastport
 This specifies the UDP port number.  It is possible to use the same multicast
 address on a network with the openais services configured for different
 UDP ports.
 
+.TP
+nodeid
+This configuration option is optional when using IPv4 and required when using
+IPv6.  This is a 32 bit value specifying the node identifier delivered to the
+cluster membership service.  If this is not specified with IPv4, the node id
+will be determined from the 32 bit IP address the system is bound to.
+
+The node identifier value of zero is reserved and should not be used.
+
 .PP
 Within the 
 .B totem 

+ 29 - 11
man/openais_overview.8

@@ -41,7 +41,7 @@ faults.  The API consists of Availability Management Framework (AMF) which
 provides application failover, Cluster Membership (CLM), Checkpointing (CKPT),
 Eventing (EVT), Messaging (MSG), and Distributed Locking (DLOCK).
 
-Currently Messaging and Distributed Locking are unimplemented.
+Currently Messaging is unimplemented.
 
 Faults occur for various reasons:
 .PP
@@ -169,6 +169,26 @@ of the makefile.
 -lais Specify this to get access to all AIS libraries without specifying
 each library individually.
 
+.SH IPv6
+The openais project supports both IPv4 and IPv6 network addresses.  The entire
+cluster must use either IPv4 or IPv6 for the cluster communication mechanism.
+In order to use IPv6, IPv6 addresses must be specified in the bindnetaddr and
+mcastaddr fields in the configuration file.  The nodeid field must also be
+set.
+
+An example of this is:
+nodeid: 2
+bindnetaddr: fec0::1:a800:4ff:fe00:20
+mcastaddr: ff05::1
+
+To configure a host for IPv6, use the ifconfig program to add interfaces:
+box20: ifconfig eth0 add fec0::1:a800:4ff:fe00:20/64
+box30: ifconfig eth0 add fec0::1:a800:4ff:fe00:30/64
+
+If the /64 is not specified, a route for the IPv6 network will not be configured
+which will cause significant problems.  Make sure a route is available for
+IPv6 traffic.
+
 .SH ARCHITECTURE
 The AIS libraries are a thin IPC interface to the openais executive.  The
 openais executive provides services for the SA Forum AIS libraries as well
@@ -186,18 +206,16 @@ authenticate all messages.  The openais executive library uses SOBER-128
 as a pseudo random number generator.  The EVS library feeds the PRNG using
 the /dev/random Linux device.
 .PP
-.SH BUGS
-The openais libraries are not particularly compliant with every aspect of the
-SA Forum's AIS specification.  The APIs themselves are consistent, but some of
-the return values and other details are not quite right yet.  The project does
-intend to be fully compliant with SAF specifications in 2005.
+.SH SAFTEST COMPLIANCE
+The openais libraries are now nearly compliant with every aspect of the SA
+Forum's AIS specification.  The AMF service, however, is not compliant with the
+B.01.01 specification.  The remaining services pass most of the tests of the 
+saftest suite against the B.01.01 specification.
 
-The AMF that is currently available is AMF A.01.01.  The rest of the services
-are of the B.01.01 specification.  This is a limitation for those developers that
-desire AMF B.01.01.  The project intends to resolve this inconsistently in 2005.
+.SH BUGS
+The openais project does not currently implement the messaging service.
+The distributed locking service is buggy and incomplete.
 
-The openais project does not currently implement the messaging service or
-distributed locking service.
 .SH "SEE ALSO"
 .BR openais.conf (5),
 .BR evs_overview (8)

+ 14 - 7
test/evsbench.c

@@ -58,32 +58,39 @@ int outstanding = 0;
 
 
 
-void evs_deliver_fn (struct in_addr source_addr, void *msg, int msg_len)
+void evs_deliver_fn (struct evs_address *source_addr, void *msg, int msg_len)
 {
 	outstanding--;
 // printf ("Delivering message %s\n", msg);
 }
 
 void evs_confchg_fn (
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries)
+	struct evs_address *member_list, int member_list_entries,
+	struct evs_address *left_list, int left_list_entries,
+	struct evs_address *joined_list, int joined_list_entries)
 {
 	int i;
+	char buf[1024];
 
 	printf ("CONFIGURATION CHANGE\n");
 	printf ("--------------------\n");
 	printf ("New configuration\n");
 	for (i = 0; i < member_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (member_list[i]));
+		inet_ntop (member_list[i].family, member_list[i].addr,
+			buf, sizeof (buf));
+		printf ("%s\n", buf);
 	}
 	printf ("Members Left:\n");
 	for (i = 0; i < left_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (left_list[i]));
+		inet_ntop (left_list[i].family, left_list[i].addr,
+			buf, sizeof (buf));
+		printf ("%s\n", buf);
 	}
 	printf ("Members Joined:\n");
 	for (i = 0; i < joined_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (joined_list[i]));
+		inet_ntop (joined_list[i].family, joined_list[i].addr,
+			buf, sizeof (buf));
+		printf ("%s\n", buf);
 	}
 }
 

+ 28 - 14
test/testevs.c

@@ -42,7 +42,7 @@
 char *delivery_string;
 
 int deliveries = 0;
-void evs_deliver_fn (struct in_addr source_addr, void *msg, int msg_len)
+void evs_deliver_fn (struct evs_address *source_addr, void *msg, int msg_len)
 {
 	char *buf = msg;
 
@@ -53,25 +53,32 @@ void evs_deliver_fn (struct in_addr source_addr, void *msg, int msg_len)
 }
 
 void evs_confchg_fn (
-	struct in_addr *member_list, int member_list_entries,
-	struct in_addr *left_list, int left_list_entries,
-	struct in_addr *joined_list, int joined_list_entries)
+	struct evs_address *member_list, int member_list_entries,
+	struct evs_address *left_list, int left_list_entries,
+	struct evs_address *joined_list, int joined_list_entries)
 {
 	int i;
+	char buf[256];
 
 	printf ("CONFIGURATION CHANGE\n");
 	printf ("--------------------\n");
 	printf ("New configuration\n");
 	for (i = 0; i < member_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (member_list[i]));
+                inet_ntop (member_list[i].family, member_list[i].addr,
+                        buf, sizeof (buf));
+                printf ("%s\n", buf);
 	}
 	printf ("Members Left:\n");
 	for (i = 0; i < left_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (left_list[i]));
+                inet_ntop (left_list[i].family, left_list[i].addr,
+                        buf, sizeof (buf));
+                printf ("%s\n", buf);
 	}
 	printf ("Members Joined:\n");
 	for (i = 0; i < joined_list_entries; i++) {
-		printf ("%s\n", inet_ntoa (joined_list[i]));
+                inet_ntop (joined_list[i].family, joined_list[i].addr,
+                        buf, sizeof (buf));
+                printf ("%s\n", buf);
 	}
 }
 
@@ -98,9 +105,10 @@ int main (void)
 	evs_error_t result;
 	int i = 0;
 	int fd;
-	struct in_addr member_list[16];
-	struct in_addr local_addr;
+	struct evs_address member_list[16];
+	struct evs_address local_addr;
 	int member_list_entries = sizeof (member_list) / sizeof (struct in_addr);
+	char buf[1024];
 
 	result = evs_initialize (&handle, &callbacks);
 	if (result != EVS_OK) {
@@ -108,12 +116,18 @@ int main (void)
 		exit (0);
 	}
 	
-	result = evs_membership_get (handle, &local_addr, member_list, &member_list_entries);
-	printf ("Current membership from evs_membership_get entries %d\n", member_list_entries);
+	result = evs_membership_get (handle, &local_addr,
+		member_list, &member_list_entries);
+	printf ("Current membership from evs_membership_get entries %d\n",
+		member_list_entries);
 	for (i = 0; i < member_list_entries; i++) {
-		printf ("Member [%d] is %s\n", i, inet_ntoa (member_list[i]));
+		inet_ntop (member_list[i].family, member_list[i].addr,
+			buf, sizeof (buf));
+		printf ("member [%d] is %s\n", i, buf);
 	}
-	printf ("local processor from evs_membership_get %s\n", inet_ntoa (local_addr));
+	inet_ntop (local_addr.family, local_addr.addr,
+		buf, sizeof (buf));
+	printf ("local processor from evs_membership_get %s\n", buf);
 
 	printf ("Init result %d\n", result);
 	result = evs_join (handle, groups, 3);
@@ -137,7 +151,7 @@ try_again_one:
 		result = evs_mcast_joined (handle, EVS_TYPE_AGREED,
 			&iov, 1);
 		if (result == EVS_ERR_TRY_AGAIN) {
-printf ("try again\n");
+//printf ("try again\n");
 			goto try_again_one;
 		}
 		result = evs_dispatch (handle, EVS_DISPATCH_ALL);

Некоторые файлы не были показаны из-за большого количества измененных файлов