summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/client/ctdb_client.c10
-rw-r--r--ctdb/common/ctdb_util.c19
-rw-r--r--ctdb/common/system_aix.c2
-rw-r--r--ctdb/common/system_linux.c160
-rw-r--r--ctdb/include/ctdb_private.h19
-rw-r--r--ctdb/server/ctdb_takeover.c44
-rw-r--r--ctdb/tools/ctdb.c9
7 files changed, 156 insertions, 107 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 04befd05cb6..fd9003d1076 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/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/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index cb535115b42..a92a53f1957 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/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/ctdb/common/system_aix.c b/ctdb/common/system_aix.c
index d455ac73dd7..8742a393c9d 100644
--- a/ctdb/common/system_aix.c
+++ b/ctdb/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/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
index fb50c6b29b2..32db545b09f 100644
--- a/ctdb/common/system_linux.c
+++ b/ctdb/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/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index 2d595ff3a2f..8127fd1e06d 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/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/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c
index 1f1111f1339..d9ac49d806e 100644
--- a/ctdb/server/ctdb_takeover.c
+++ b/ctdb/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,9 @@ 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 +1736,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 +1751,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 +1774,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 +1798,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/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index 6df78130d6e..9d6752f13f0 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/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;