diff --git a/configure.ac b/configure.ac index 3b5d5ed..29eec20 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,31 @@ AC_ARG_ENABLE(asserts, AC_MSG_RESULT(${DEBUG_OPTS:-none}) AC_SUBST(DEBUG_OPTS) +AC_ARG_ENABLE(ipv6, + AS_HELP_STRING([--disable-ipv6], + [disable ipv6 support (default is autodetect)]), + ac_cv_have_ipv6=$enable_ipv6,) + +dnl check for ipv6 +if test "$ac_cv_have_ipv6" != no; then + AC_CHECK_TYPES(struct in6_addr,,,[#include ]) + AC_CHECK_TYPES(struct ip6_hdr,,,[#include ]) + AC_CHECK_DECLS(AF_INET6,,,[#include ]) + AC_MSG_CHECKING(for IPv6 headers and structures) + ac_cv_have_ipv6=no + + if test "$ac_cv_type_struct_in6_addr" = yes; then + if test "$ac_cv_type_struct_ip6_hdr" = yes; then + if test "$ac_cv_have_decl_AF_INET6" = yes; then + ac_cv_have_ipv6=yes + AC_DEFINE([HAVE_IP6], 1, [Define to enable IPv6 support]) + fi + fi + fi + AC_MSG_RESULT($ac_cv_have_ipv6) +fi + + AC_CONFIG_FILES([ Makefile ]) diff --git a/uvrrpd.c b/uvrrpd.c index 4b1b0e5..ff4b7c5 100644 --- a/uvrrpd.c +++ b/uvrrpd.c @@ -36,7 +36,9 @@ #include "vrrp_net.h" #include "vrrp_adv.h" #include "vrrp_arp.h" +#ifdef HAVE_IP6 #include "vrrp_na.h" +#endif #include "vrrp_options.h" #include "vrrp_exec.h" #include "vrrp_ctrl.h" @@ -115,10 +117,12 @@ int main(int argc, char *argv[]) if (vrrp_arp_init(&vnet) != 0) exit(EXIT_FAILURE); } +#ifdef HAVE_IP6 else if (vnet.family == AF_INET6) { if (vrrp_na_init(&vnet) != 0) exit(EXIT_FAILURE); } +#endif /* daemonize */ if (background) { @@ -145,8 +149,10 @@ int main(int argc, char *argv[]) if (vnet.family == AF_INET) vrrp_arp_cleanup(&vnet); +#ifdef HAVE_IP6 else /* AF_INET6 */ vrrp_na_cleanup(&vnet); +#endif vrrp_cleanup(&vrrp); vrrp_exec_cleanup(&vrrp); diff --git a/vrrp_adv.c b/vrrp_adv.c index 9cada1b..b7272da 100644 --- a/vrrp_adv.c +++ b/vrrp_adv.c @@ -25,7 +25,9 @@ #include // ETH_P_IP = 0x0800, ETH_P_IPV6 = 0x86DD #include #include +#ifdef HAVE_IP6 #include +#endif #include "log.h" #include "vrrp.h" @@ -34,7 +36,10 @@ /* VRRP multicast group */ #define INADDR_VRRP_GROUP 0xe0000012 /* 224.0.0.18 */ + +#ifdef HAVE_IP6 #define IN6ADDR_VRRP_GROUP "FF02::12" +#endif #define ETHDR_SIZE sizeof(struct ether_header) @@ -76,9 +81,10 @@ static int vrrp_adv_eth_build(struct iovec *iov, const uint8_t vrid, hdr->ether_shost[5] = vrid; if (family == AF_INET) hdr->ether_type = htons(ETH_P_IP); +#ifdef HAVE_IP6 else /* AF_INET6 */ hdr->ether_type = htons(ETH_P_IPV6); - +#endif iov->iov_len = ETHDR_SIZE; return 0; @@ -121,6 +127,7 @@ static int vrrp_adv_ip4_build(struct iovec *iov, const struct vrrp_net *vnet) /** * vrrp_adv_ip6_build() - build VRRP IPv6 advertisement */ +#ifdef HAVE_IP6 static int vrrp_adv_ip6_build(struct iovec *iov, const struct vrrp_net *vnet) { iov->iov_base = malloc(sizeof(struct ip6_hdr)); @@ -148,6 +155,7 @@ static int vrrp_adv_ip6_build(struct iovec *iov, const struct vrrp_net *vnet) return 0; } +#endif /* HAVE_IP6 */ /** * vrrp_net_adv_build() - build VRRP adv pkt @@ -191,11 +199,13 @@ static int vrrp_adv_build(struct iovec *iov, const struct vrrp_net *vnet, vip_addr[pos] = vip_ptr->ip_addr.s_addr; ++pos; } +#ifdef HAVE_IP6 else { /* AF_INET6 */ memcpy(&vip_addr[pos], &vip_ptr->ip_addr6, sizeof(struct in6_addr)); pos += 4; } +#endif /* HAVE_IP6 */ ++naddr; if (naddr > vrrp->naddr) { @@ -268,8 +278,10 @@ int vrrp_adv_init(struct vrrp_net *vnet, const struct vrrp *vrrp) if (vnet->family == AF_INET) status |= vrrp_adv_ip4_build(&vnet->__adv[1], vnet); +#ifdef HAVE_IP6 else /* AF_INET6 */ status |= vrrp_adv_ip6_build(&vnet->__adv[1], vnet); +#endif /* HAVE_IP6 */ status |= vrrp_adv_build(&vnet->__adv[2], vnet, vrrp); diff --git a/vrrp_adv.h b/vrrp_adv.h index 8d24e22..50c383e 100644 --- a/vrrp_adv.h +++ b/vrrp_adv.h @@ -29,8 +29,10 @@ int vrrp_adv_send(struct vrrp_net *vnet); int vrrp_adv_send_zero(struct vrrp_net *vnet); uint16_t vrrp_adv_chksum(struct vrrp_net *vnet, struct vrrphdr *pkt, uint32_t saddr, uint32_t daddr); +#ifdef HAVE_IP6 uint16_t vrrp_adv_ip6_chksum(struct vrrp_net *vnet, struct vrrphdr *pkt, struct in6_addr *saddr, struct in6_addr *daddr); +#endif /* HAVE_IP6 */ /** * vrrp_adv_get_version() - get version_type from received adv pkt diff --git a/vrrp_ip6.c b/vrrp_ip6.c index a05f924..8006fb6 100644 --- a/vrrp_ip6.c +++ b/vrrp_ip6.c @@ -19,6 +19,7 @@ * along with uvrrpd. If not, see . */ +#ifdef HAVE_IP6 #include #include @@ -341,3 +342,5 @@ struct vrrp_ipx VRRP_IP6 = { .ipx_pton = vrrp_ip6_pton, .ipx_ntop = vrrp_ip6_ntop }; + +#endif /* HAVE_IP6 */ diff --git a/vrrp_ipx.h b/vrrp_ipx.h index 9c63da9..dd1ba11 100644 --- a/vrrp_ipx.h +++ b/vrrp_ipx.h @@ -43,7 +43,9 @@ struct vrrp_ipx_header { */ union vrrp_ipx_addr { struct in_addr addr; +#ifdef HAVE_IP6 struct in6_addr addr6; +#endif }; /** @@ -86,7 +88,9 @@ struct vrrp_ipx { /* IP4 and IP6 internal modules */ extern struct vrrp_ipx VRRP_IP4; /* IPv4 module */ +#ifdef HAVE_IP6 extern struct vrrp_ipx VRRP_IP6; /* IPv6 module */ +#endif /** * vrrp_ipx_set() - Set l3 helper for vrrp_net @@ -96,10 +100,11 @@ static inline struct vrrp_ipx *vrrp_ipx_set(int family) if (family == AF_INET) { return &VRRP_IP4; } +#ifdef HAVE_IP6 if (family == AF_INET6) { return &VRRP_IP6; } - +#endif return NULL; } diff --git a/vrrp_na.c b/vrrp_na.c index 86c2e9b..b470745 100644 --- a/vrrp_na.c +++ b/vrrp_na.c @@ -21,6 +21,8 @@ * along with uvrrpd. If not, see . */ +#ifdef HAVE_IP6 + #include #include #include @@ -239,3 +241,5 @@ void vrrp_na_cleanup(struct vrrp_net *vnet) } } + +#endif /* HAVE_IP6 */ diff --git a/vrrp_na.h b/vrrp_na.h index a61c4ca..cd088e2 100644 --- a/vrrp_na.h +++ b/vrrp_na.h @@ -19,6 +19,8 @@ * along with uvrrpd. If not, see . */ +#ifdef HAVE_IP6 + #ifndef _VRRP_NA_H_ #define _VRRP_NA_H_ @@ -27,3 +29,5 @@ void vrrp_na_cleanup(struct vrrp_net *vnet); int vrrp_na_send(struct vrrp_net *vnet); #endif /* _VRRP_NA_H_ */ + +#endif /* HAVE_IP6 */ diff --git a/vrrp_net.c b/vrrp_net.c index 7893983..27dd256 100644 --- a/vrrp_net.c +++ b/vrrp_net.c @@ -167,12 +167,14 @@ int vrrp_net_vif_getaddr(struct vrrp_net *vnet) ((struct sockaddr_in *) ifa->ifa_addr)-> sin_addr.s_addr; } +#ifdef HAVE_IP6 else { /* AF_INET6 */ struct sockaddr_in6 *src = (struct sockaddr_in6 *) ifa->ifa_addr; memcpy(&vnet->vif.ip_addr6, &src->sin6_addr, sizeof(struct in6_addr)); } +#endif /* HAVE_IP6 */ } freeifaddrs(ifaddr); @@ -229,10 +231,12 @@ int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip) split_ip_netmask(vnet->family, ip, &vip->ip_addr, &vip->netmask); +#ifdef HAVE_IP6 if (vnet->family == AF_INET6) status = split_ip_netmask(vnet->family, ip, &vip->ip_addr6, &vip->netmask); +#endif /* HAVE_IP6 */ if (status != 0) { fprintf(stderr, "vrid %d :: invalid IP addr %s", vnet->vrid, diff --git a/vrrp_net.h b/vrrp_net.h index 146e36c..55d5a04 100644 --- a/vrrp_net.h +++ b/vrrp_net.h @@ -87,11 +87,14 @@ struct vrrp_recv { }; #define ip_addr ipx.addr -#define ip_addr6 ipx.addr6 #define ip_saddr s_ipx.addr #define ip_daddr d_ipx.addr + +#ifdef HAVE_IP6 +#define ip_addr6 ipx.addr6 #define ip_saddr6 s_ipx.addr6 #define ip_daddr6 d_ipx.addr6 +#endif /* HAVE_IP6 */ /** * struct vrrp_net - VRRP net structure diff --git a/vrrp_options.c b/vrrp_options.c index 4d9fb2d..741238c 100644 --- a/vrrp_options.c +++ b/vrrp_options.c @@ -60,7 +60,9 @@ static void vrrp_usage(void) " -r, --rfc version Specify protocol 'version'\n" " 2 (VRRPv2, RFC3768) by default,\n" " 3 (VRRPv3, RFC5798)\n" +#ifdef HAVE_IP6 " -6, --ipv6 IPv6 support, (only in VRRPv3)\n" +#endif /* HAVE_IP6 */ " -a, --auth pass Simple text password (only in VRRPv2)\n" " -f, --foreground Execute uvrrpd in foreground\n" " -s, --script Path of hook script (default "stringify(PATH)"/vrrp_switch.sh)\n" @@ -88,7 +90,9 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, {"start-delay", required_argument, 0, 'T'}, {"preempt", required_argument, 0, 'P'}, {"rfc", required_argument, 0, 'r'}, +#ifdef HAVE_IP6 {"ipv6", no_argument, 0, '6'}, +#endif /* HAVE_IP6 */ {"auth", required_argument, 0, 'a'}, {"foreground", no_argument, 0, 'f'}, {"script", required_argument, 0, 's'}, @@ -100,7 +104,14 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, }; while ((optc = - getopt_long(argc, argv, "v:i:p:t:T:P:r:6a:fs:F:C:dh", opts, + getopt_long(argc, argv, +#ifdef HAVE_IP6 + "v:i:p:t:T:P:r:6a:fs:F:C:dh", +#else + "v:i:p:t:T:P:r:a:fs:F:C:dh", +#endif /* HAVE_IP6 */ + opts, + NULL)) != EOF) { switch (optc) { @@ -220,11 +231,13 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, vrrp->version = (uint8_t) opt; break; +#ifdef HAVE_IP6 /* IPv6 */ case '6': /* Force RFC5798/VRRPv3 */ vrrp->version = RFC5798; vnet->family = AF_INET6; break; +#endif /* HAVE_IP6 */ /* auth */ case 'a': /* only SIMPLE password supported */ diff --git a/vrrp_state.c b/vrrp_state.c index d3c8172..267e2c2 100644 --- a/vrrp_state.c +++ b/vrrp_state.c @@ -286,13 +286,14 @@ static int vrrp_state_goto_master(struct vrrp *vrrp, struct vrrp_net *vnet) vrrp->state = MASTER; - /* IPv4 specific */ vrrp_adv_send(vnet); if (vnet->family == AF_INET) vrrp_arp_send(vnet); +#ifdef HAVE_IP6 else if (vnet->family == AF_INET6) vrrp_na_send(vnet); +#endif /* HAVE_IP6 */ /* script */ vrrp_exec(vrrp, vnet, vrrp->state);