[SCM] CTDB repository - branch master updated - b87fab857bc9b3537527be93b7f68484502d6b84

Ronnie Sahlberg sahlberg at samba.org
Wed Jun 4 05:27:26 GMT 2008


The branch, master has been updated
       via  b87fab857bc9b3537527be93b7f68484502d6b84 (commit)
       via  86d6f53512d358ff68b58dac737ffa7576c3cce6 (commit)
      from  4948574f5a290434f3edd0c052cf13f3645deec4 (commit)

http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b87fab857bc9b3537527be93b7f68484502d6b84
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 4 15:23:06 2008 +1000

    fix a comment
    
    note that we dont actually send the ipv6 "gratious arp" on the wire just yet.
    (since ipv6 doesnt use arp)
    but all the infrastructure is there when we implement sending raw neig.disc. packets

commit 86d6f53512d358ff68b58dac737ffa7576c3cce6
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 4 15:13:00 2008 +1000

    convert handling of gratious arps and their controls and helpers to
    use the ctdb_sock_addr structure so tehy work for both ipv4 and ipv6

-----------------------------------------------------------------------

Summary of changes:
 client/ctdb_client.c   |   10 ++--
 common/ctdb_util.c     |   19 ++++++
 common/system_aix.c    |    2 +-
 common/system_linux.c  |  160 ++++++++++++++++++++++++------------------------
 include/ctdb_private.h |   19 +++++-
 server/ctdb_takeover.c |   43 +++++++++----
 tools/ctdb.c           |    9 +--
 7 files changed, 155 insertions(+), 107 deletions(-)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index 04befd0..fd9003d 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -2385,27 +2385,27 @@ int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb, 
 		      struct timeval timeout, 
 		      uint32_t destnode,
-		      struct sockaddr_in *sin,
+		      ctdb_sock_addr *addr,
 		      const char *ifname)
 {
 	TDB_DATA data;
 	int32_t res;
 	int ret, len;
-	struct ctdb_control_ip_iface *gratious_arp;
+	struct ctdb_control_gratious_arp *gratious_arp;
 	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 
 
 	len = strlen(ifname)+1;
 	gratious_arp = talloc_size(tmp_ctx, 
-		offsetof(struct ctdb_control_ip_iface, iface) + len);
+		offsetof(struct ctdb_control_gratious_arp, iface) + len);
 	CTDB_NO_MEMORY(ctdb, gratious_arp);
 
-	gratious_arp->sin = *sin;
+	gratious_arp->addr = *addr;
 	gratious_arp->len = len;
 	memcpy(&gratious_arp->iface[0], ifname, len);
 
 
-	data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + len;
+	data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
 	data.dptr  = (unsigned char *)gratious_arp;
 
 	ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
diff --git a/common/ctdb_util.c b/common/ctdb_util.c
index cb53511..a92a53f 100644
--- a/common/ctdb_util.c
+++ b/common/ctdb_util.c
@@ -371,6 +371,25 @@ bool parse_ip_port(const char *addr, ctdb_sock_addr *saddr)
 }
 
 /*
+  parse an ip
+ */
+bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
+{
+	char *p;
+	bool ret;
+
+	/* now is this a ipv4 or ipv6 address ?*/
+	p = index(addr, ':');
+	if (p == NULL) {
+		ret = parse_ipv4(addr, 0, saddr);
+	} else {
+		ret = parse_ipv6(addr, 0, saddr);
+	}
+
+	return ret;
+}
+
+/*
   parse a ip/mask pair
  */
 bool parse_ip_mask(const char *s, struct sockaddr_in *ip, unsigned *mask)
diff --git a/common/system_aix.c b/common/system_aix.c
index d455ac7..8742a39 100644
--- a/common/system_aix.c
+++ b/common/system_aix.c
@@ -220,7 +220,7 @@ int ctdb_sys_close_capture_socket(void *private_data)
   saddr is the address we are trying to claim
   iface is the interface name we will be using to claim the address
  */
-int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface)
+int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
 {
 	/* We dont do grat arp on aix yet */
 	return 0;
diff --git a/common/system_linux.c b/common/system_linux.c
index fb50c6b..32db545 100644
--- a/common/system_linux.c
+++ b/common/system_linux.c
@@ -36,7 +36,7 @@
   saddr is the address we are trying to claim
   iface is the interface name we will be using to claim the address
  */
-int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface)
+int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
 {
 	int s, ret;
 	struct sockaddr sa;
@@ -48,92 +48,94 @@ int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface)
 
 	ZERO_STRUCT(sa);
 
-	/* for now, we only handle AF_INET addresses */
-	if (saddr->sin_family != AF_INET) {
-		DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address (family is %u)\n", saddr->sin_family));
-		return -1;
-	}
+	switch (addr->ip.sin_family) {
+	case AF_INET:
+		s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
+		if (s == -1){
+			DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
+			return -1;
+		}
 
-	s = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP));
-	if (s == -1){
-		DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
-		return -1;
-	}
+		/* get the mac address */
+		strcpy(if_hwaddr.ifr_name, iface);
+		ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
+		if ( ret < 0 ) {
+			close(s);
+			DEBUG(DEBUG_CRIT,(__location__ " ioctl failed\n"));
+			return -1;
+		}
+		if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) {
+			DEBUG(DEBUG_DEBUG,("Ignoring loopback arp request\n"));
+			close(s);
+			return 0;
+		}
+		if (if_hwaddr.ifr_hwaddr.sa_family != AF_LOCAL) {
+			close(s);
+			errno = EINVAL;
+			DEBUG(DEBUG_CRIT,(__location__ " not an ethernet address family (0x%x)\n",
+				 if_hwaddr.ifr_hwaddr.sa_family));
+			return -1;
+		}
 
-	/* get the mac address */
-	strcpy(if_hwaddr.ifr_name, iface);
-	ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
-	if ( ret < 0 ) {
-		close(s);
-		DEBUG(DEBUG_CRIT,(__location__ " ioctl failed\n"));
-		return -1;
-	}
-	if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) {
-		DEBUG(DEBUG_DEBUG,("Ignoring loopback arp request\n"));
-		close(s);
-		return 0;
-	}
-	if (if_hwaddr.ifr_hwaddr.sa_family != AF_LOCAL) {
-		close(s);
-		errno = EINVAL;
-		DEBUG(DEBUG_CRIT,(__location__ " not an ethernet address family (0x%x)\n",
-			 if_hwaddr.ifr_hwaddr.sa_family));
-		return -1;
-	}
 
+		memset(buffer, 0 , 64);
+		eh = (struct ether_header *)buffer;
+		memset(eh->ether_dhost, 0xff, ETH_ALEN);
+		memcpy(eh->ether_shost, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+		eh->ether_type = htons(ETHERTYPE_ARP);
+	
+		ah = (struct arphdr *)&buffer[sizeof(struct ether_header)];
+		ah->ar_hrd = htons(ARPHRD_ETHER);
+		ah->ar_pro = htons(ETH_P_IP);
+		ah->ar_hln = ETH_ALEN;
+		ah->ar_pln = 4;
+
+		/* send a gratious arp */
+		ah->ar_op  = htons(ARPOP_REQUEST);
+		ptr = (char *)&ah[1];
+		memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+		ptr+=ETH_ALEN;
+		memcpy(ptr, &addr->ip.sin_addr, 4);	  
+		ptr+=4;
+		memset(ptr, 0, ETH_ALEN); 
+		ptr+=ETH_ALEN;
+		memcpy(ptr, &addr->ip.sin_addr, 4);	  
+		ptr+=4;
+	
+		strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
+		ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+		if (ret < 0 ){
+			close(s);
+			DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+			return -1;
+		}	
+
+		/* send unsolicited arp reply broadcast */
+		ah->ar_op  = htons(ARPOP_REPLY);
+		ptr = (char *)&ah[1];
+		memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+		ptr+=ETH_ALEN;
+		memcpy(ptr, &addr->ip.sin_addr, 4);	  
+		ptr+=4;
+		memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
+		ptr+=ETH_ALEN;
+		memcpy(ptr, &addr->ip.sin_addr, 4);	  
+		ptr+=4;
+
+		strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
+		ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
+		if (ret < 0 ){
+			DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+			return -1;
+		}
 
-	memset(buffer, 0 , 64);
-	eh = (struct ether_header *)buffer;
-	memset(eh->ether_dhost, 0xff, ETH_ALEN);
-	memcpy(eh->ether_shost, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
-	eh->ether_type = htons(ETHERTYPE_ARP);
-
-	ah = (struct arphdr *)&buffer[sizeof(struct ether_header)];
-	ah->ar_hrd = htons(ARPHRD_ETHER);
-	ah->ar_pro = htons(ETH_P_IP);
-	ah->ar_hln = ETH_ALEN;
-	ah->ar_pln = 4;
-
-	/* send a gratious arp */
-	ah->ar_op  = htons(ARPOP_REQUEST);
-	ptr = (char *)&ah[1];
-	memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
-	ptr+=ETH_ALEN;
-	memcpy(ptr, &saddr->sin_addr, 4);	  
-	ptr+=4;
-	memset(ptr, 0, ETH_ALEN); 
-	ptr+=ETH_ALEN;
-	memcpy(ptr, &saddr->sin_addr, 4);	  
-	ptr+=4;
-
-	strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
-	ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
-	if (ret < 0 ){
 		close(s);
-		DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
-		return -1;
-	}
-
-	/* send unsolicited arp reply broadcast */
-	ah->ar_op  = htons(ARPOP_REPLY);
-	ptr = (char *)&ah[1];
-	memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
-	ptr+=ETH_ALEN;
-	memcpy(ptr, &saddr->sin_addr, 4);	  
-	ptr+=4;
-	memcpy(ptr, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN);
-	ptr+=ETH_ALEN;
-	memcpy(ptr, &saddr->sin_addr, 4);	  
-	ptr+=4;
-
-	strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
-	ret = sendto(s, buffer, 64, 0, &sa, sizeof(sa));
-	if (ret < 0 ){
-		DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n"));
+		break;
+	default:
+		DEBUG(DEBUG_CRIT,(__location__ " not an ipv4 address (family is %u)\n", addr->ip.sin_family));
 		return -1;
 	}
 
-	close(s);
 	return 0;
 }
 
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 2d595ff..8127fd1 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -567,9 +567,8 @@ struct ctdb_control_killtcp {
 
 /*
   struct holding a sockaddr_in and an interface name,
-  used for send_gratious_arp and also add/remove public addresses
+  used to add/remove public addresses
  */
-//struct ctdb_control_gratious_arp {
 struct ctdb_control_ip_iface {
 	struct sockaddr_in sin;
 	uint32_t mask;
@@ -578,6 +577,17 @@ struct ctdb_control_ip_iface {
 };
 
 /*
+  struct holding a ctdb_sock_addr and an interface name,
+  used for send_gratious_arp
+ */
+struct ctdb_control_gratious_arp {
+	ctdb_sock_addr addr;
+	uint32_t mask;
+	uint32_t len;
+	char iface[1];
+};
+
+/*
   struct for tcp_add and tcp_remove controls
  */
 struct ctdb_control_tcp_vnn {
@@ -1166,7 +1176,7 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
 
 
 /* from takeover/system.c */
-int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface);
+int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface);
 bool ctdb_sys_have_ip(struct sockaddr_in ip);
 int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, 
 		      const ctdb_sock_addr *src,
@@ -1225,6 +1235,7 @@ int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
 void ctdb_start_freeze(struct ctdb_context *ctdb);
 
 bool parse_ip_port(const char *s, ctdb_sock_addr *saddr);
+bool parse_ip(const char *s, ctdb_sock_addr *saddr);
 
 int ctdb_sys_open_capture_socket(const char *iface, void **private_data);
 int ctdb_sys_close_capture_socket(void *private_data);
@@ -1249,7 +1260,7 @@ int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb, 
 		      struct timeval timeout, 
 		      uint32_t destnode,
-		      struct sockaddr_in *sin,
+		      ctdb_sock_addr *addr,
 		      const char *ifname);
 
 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb, 
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index 1f1111f..2eec1f0 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -36,7 +36,7 @@
 struct ctdb_takeover_arp {
 	struct ctdb_context *ctdb;
 	uint32_t count;
-	struct sockaddr_in sin;
+	ctdb_sock_addr addr;
 	struct ctdb_tcp_array *tcparray;
 	struct ctdb_vnn *vnn;
 };
@@ -73,7 +73,7 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *
 	struct ctdb_tcp_array *tcparray;
 
 
-	ret = ctdb_sys_send_arp(&arp->sin, arp->vnn->iface);
+	ret = ctdb_sys_send_arp(&arp->addr, arp->vnn->iface);
 	if (ret != 0) {
 		DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed (%s)\n", strerror(errno)));
 	}
@@ -123,10 +123,27 @@ static void takeover_ip_callback(struct ctdb_context *ctdb, int status,
 	struct takeover_callback_state *state = 
 		talloc_get_type(private_data, struct takeover_callback_state);
 	struct ctdb_takeover_arp *arp;
-	char *ip = inet_ntoa(state->sin->sin_addr);
 	struct ctdb_tcp_array *tcparray;
 
 	if (status != 0) {
+		char ip[128] = "";
+
+		switch(state->sin->sin_family){
+		case AF_INET:
+			if (inet_ntop(AF_INET, &state->sin->sin_addr, ip, sizeof(ip)) == NULL) {
+				DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
+			}
+			break;
+		case AF_INET6:
+			if (inet_ntop(AF_INET6, &state->sin->sin_addr, ip, sizeof(ip)) == NULL) {
+				DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
+			}
+			break;
+		default:
+			DEBUG(DEBUG_ERR, (__location__ " cant convert this address family to a string\n"));
+			break;
+		}
+	
 		DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
 			 ip, state->vnn->iface));
 		ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
@@ -145,7 +162,8 @@ static void takeover_ip_callback(struct ctdb_context *ctdb, int status,
 	if (!arp) goto failed;
 	
 	arp->ctdb = ctdb;
-	arp->sin = *state->sin;
+/* qqq convert state->sin from sockaddr_in to ctdb_sock_addr no need to cast then*/
+	arp->addr.ip = *((ctdb_addr_in *)state->sin);
 	arp->vnn = state->vnn;
 
 	tcparray = state->vnn->tcp_array;
@@ -1717,7 +1735,7 @@ void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
 
 struct control_gratious_arp {
 	struct ctdb_context *ctdb;
-	struct sockaddr_in sin;
+	ctdb_sock_addr addr;
 	const char *iface;
 	int count;
 };
@@ -1732,7 +1750,7 @@ static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
 	struct control_gratious_arp *arp = talloc_get_type(private_data, 
 							struct control_gratious_arp);
 
-	ret = ctdb_sys_send_arp(&arp->sin, arp->iface);
+	ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp failed (%s)\n", strerror(errno)));
 	}
@@ -1755,23 +1773,22 @@ static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
  */
 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
 {
-	struct ctdb_control_ip_iface *gratious_arp = (struct ctdb_control_ip_iface *)indata.dptr;
+	struct ctdb_control_gratious_arp *gratious_arp = (struct ctdb_control_gratious_arp *)indata.dptr;
 	struct control_gratious_arp *arp;
 
-
 	/* verify the size of indata */
-	if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
-		DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
+	if (indata.dsize < offsetof(struct ctdb_control_gratious_arp, iface)) {
+		DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n", indata.dsize, offsetof(struct ctdb_control_gratious_arp, iface)));
 		return -1;
 	}
 	if (indata.dsize != 
-		( offsetof(struct ctdb_control_ip_iface, iface)
+		( offsetof(struct ctdb_control_gratious_arp, iface)
 		+ gratious_arp->len ) ){
 
 		DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
 			"but should be %u bytes\n", 
 			 (unsigned)indata.dsize, 
-			 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+gratious_arp->len)));
+			 (unsigned)(offsetof(struct ctdb_control_gratious_arp, iface)+gratious_arp->len)));
 		return -1;
 	}
 
@@ -1780,7 +1797,7 @@ int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indat
 	CTDB_NO_MEMORY(ctdb, arp);
 
 	arp->ctdb  = ctdb;
-	arp->sin   = gratious_arp->sin;
+	arp->addr   = gratious_arp->addr;
 	arp->iface = talloc_strdup(arp, gratious_arp->iface);
 	CTDB_NO_MEMORY(ctdb, arp->iface);
 	arp->count = 0;
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 6df7813..9d6752f 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -837,19 +837,18 @@ static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
 {
 	int ret;
-	struct sockaddr_in sin;
+	ctdb_sock_addr addr;
 
 	if (argc < 2) {
 		usage();
 	}
 
-	sin.sin_family = AF_INET;
-	if (inet_aton(argv[0], &sin.sin_addr) == 0) {
-		DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
+	if (!parse_ip(argv[0], &addr)) {
+		DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
 		return -1;
 	}
 
-	ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &sin, argv[1]);
+	ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
 		return ret;


-- 
CTDB repository


More information about the samba-cvs mailing list