1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

ctdb-common: Fix error handling when sending ARPs

There are numerous places in the code where errno can be lost causing
the wrong error to be printed by a caller.  Change ctdb_sys_send_arp()
to always return a useful errno on error instead of returning -1 and
sometimes having errno set correctly.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
Martin Schwenke 2018-08-10 17:23:56 +10:00 committed by Amitay Isaacs
parent 2ebb25dfc8
commit 50a6d15256
2 changed files with 34 additions and 29 deletions

View File

@ -172,7 +172,7 @@ static uint16_t ip6_checksum(uint16_t *data, size_t n, struct ip6_hdr *ip6)
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
{
int s, ret;
int s;
struct sockaddr_ll sall = {0};
struct ether_header *eh;
struct arphdr *ah;
@ -189,41 +189,42 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
char *ptr;
char bdcast[] = {0xff,0xff,0xff,0xff,0xff,0xff};
struct ifreq ifr = {{{0}}};
int ret = 0;
s = socket(AF_PACKET, SOCK_RAW, 0);
if (s == -1) {
ret = errno;
DBG_ERR("Failed to open raw socket\n");
return -1;
return ret;
}
DBG_DEBUG("Created SOCKET FD:%d for sending arp\n", s);
/* Find interface */
strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
ret = errno;
DBG_ERR("Interface '%s' not found\n", iface);
close(s);
return -1;
goto fail;
}
/* Get MAC address */
strlcpy(if_hwaddr.ifr_name, iface, sizeof(if_hwaddr.ifr_name));
ret = ioctl(s, SIOCGIFHWADDR, &if_hwaddr);
if ( ret < 0 ) {
close(s);
ret = errno;
DBG_ERR("ioctl failed\n");
return -1;
goto fail;
}
if (ARPHRD_LOOPBACK == if_hwaddr.ifr_hwaddr.sa_family) {
ret = 0;
D_DEBUG("Ignoring loopback arp request\n");
close(s);
return 0;
goto fail;
}
if (if_hwaddr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
close(s);
errno = EINVAL;
ret = EINVAL;
DBG_ERR("Not an ethernet address family (0x%x)\n",
if_hwaddr.ifr_hwaddr.sa_family);
return -1;
goto fail;;
}
/* Set up most of destination address structure */
@ -262,10 +263,10 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
ret = sendto(s,buffer, 64, 0,
(struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
close(s);
if (ret < 0 ) {
ret = errno;
DBG_ERR("Failed sendto\n");
return -1;
goto fail;
}
/* send unsolicited arp reply broadcast */
@ -282,10 +283,10 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
ret = sendto(s, buffer, 64, 0,
(struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
if (ret < 0 ) {
ret = errno;
DBG_ERR("Failed sendto\n");
close(s);
return -1;
goto fail;
}
close(s);
@ -314,9 +315,9 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
ret = inet_pton(AF_INET6, "ff02::1", &ip6->ip6_dst);
if (ret != 1) {
close(s);
ret = errno;
DBG_ERR("Failed inet_pton\n");
return -1;
goto fail;
}
nd_na = (struct nd_neighbor_advert *)(ip6+1);
@ -339,21 +340,26 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
ret = sendto(s, buffer, sizeof(buffer),
0, (struct sockaddr *)&sall, sizeof(sall));
if (ret < 0 ){
close(s);
if (ret < 0 ) {
ret = errno;
DBG_ERR("Failed sendto\n");
return -1;
goto fail;
}
close(s);
break;
default:
ret = EINVAL;
DBG_ERR("Not an ipv4/ipv6 address (family is %u)\n",
addr->ip.sin_family);
return -1;
goto fail;
}
return 0;
fail:
close(s);
return ret;
}
#else /* HAVE_PACKETSOCKET */
@ -361,8 +367,7 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface)
{
/* Not implemented */
errno = ENOSYS;
return -1;
return ENOSYS;
}
#endif /* HAVE_PACKETSOCKET */

View File

@ -376,8 +376,8 @@ static void ctdb_control_send_arp(struct tevent_context *ev,
ret = ctdb_sys_send_arp(&arp->addr, iface);
if (ret != 0) {
DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed on iface '%s' (%s)\n",
iface, strerror(errno)));
DBG_ERR("Failed to send ARP on interface %s: %s\n",
iface, strerror(ret));
}
tcparray = arp->tcparray;
@ -2115,8 +2115,8 @@ static void send_gratious_arp(struct tevent_context *ev,
ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp on iface '%s' failed (%s)\n",
arp->iface, strerror(errno)));
DBG_ERR("Failed to send gratuitous ARP on iface %s: %s\n",
arp->iface, strerror(ret));
}