|
|
cead2e |
From dd9a0db422716dd9bbc329a6e2f23ee3d55d2008 Mon Sep 17 00:00:00 2001
|
|
|
cead2e |
From: Quentin Armitage <quentin@armitage.org.uk>
|
|
|
cead2e |
Date: Mon, 27 Mar 2017 11:26:44 +0100
|
|
|
cead2e |
Subject: [PATCH 1/3] Handle not being able to load ip_tables or ip6_tables
|
|
|
cead2e |
modules
|
|
|
cead2e |
|
|
|
cead2e |
When running in a docker container it isn't possible to load kernel
|
|
|
cead2e |
modules, so we need to cleanly handle a failure to load the modules.
|
|
|
cead2e |
|
|
|
cead2e |
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
|
|
|
cead2e |
---
|
|
|
cead2e |
keepalived/core/global_data.c | 2 -
|
|
|
cead2e |
keepalived/include/global_data.h | 2 -
|
|
|
cead2e |
keepalived/include/vrrp.h | 5 +
|
|
|
cead2e |
keepalived/include/vrrp_ipset.h | 4 +-
|
|
|
cead2e |
keepalived/include/vrrp_iptables.h | 7 +-
|
|
|
cead2e |
keepalived/include/vrrp_iptables_calls.h | 2 +-
|
|
|
cead2e |
keepalived/vrrp/vrrp.c | 53 ++++++--
|
|
|
cead2e |
keepalived/vrrp/vrrp_daemon.c | 13 +-
|
|
|
cead2e |
keepalived/vrrp/vrrp_ipaddress.c | 137 ++++++++++++++++---
|
|
|
cead2e |
keepalived/vrrp/vrrp_ipset.c | 73 +++++++---
|
|
|
cead2e |
keepalived/vrrp/vrrp_iptables.c | 225 +++++++++++++++++++------------
|
|
|
cead2e |
keepalived/vrrp/vrrp_iptables_calls.c | 108 +++++++--------
|
|
|
cead2e |
12 files changed, 421 insertions(+), 210 deletions(-)
|
|
|
cead2e |
|
|
|
cead2e |
diff --git a/keepalived/core/global_data.c b/keepalived/core/global_data.c
|
|
|
cead2e |
index d934f286..21c06c1c 100644
|
|
|
cead2e |
--- a/keepalived/core/global_data.c
|
|
|
cead2e |
+++ b/keepalived/core/global_data.c
|
|
|
cead2e |
@@ -98,8 +98,6 @@ set_vrrp_defaults(data_t * data)
|
|
|
cead2e |
data->vrrp_higher_prio_send_advert = false;
|
|
|
cead2e |
data->vrrp_version = VRRP_VERSION_2;
|
|
|
cead2e |
strcpy(data->vrrp_iptables_inchain, "INPUT");
|
|
|
cead2e |
- data->block_ipv4 = false;
|
|
|
cead2e |
- data->block_ipv6 = false;
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
data->using_ipsets = true;
|
|
|
cead2e |
strcpy(data->vrrp_ipset_address, "keepalived");
|
|
|
cead2e |
diff --git a/keepalived/include/global_data.h b/keepalived/include/global_data.h
|
|
|
cead2e |
index 6547ddac..eea34f75 100644
|
|
|
cead2e |
--- a/keepalived/include/global_data.h
|
|
|
cead2e |
+++ b/keepalived/include/global_data.h
|
|
|
cead2e |
@@ -99,8 +99,6 @@ typedef struct _data {
|
|
|
cead2e |
int vrrp_version; /* VRRP version (2 or 3) */
|
|
|
cead2e |
char vrrp_iptables_inchain[XT_EXTENSION_MAXNAMELEN];
|
|
|
cead2e |
char vrrp_iptables_outchain[XT_EXTENSION_MAXNAMELEN];
|
|
|
cead2e |
- bool block_ipv4;
|
|
|
cead2e |
- bool block_ipv6;
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
bool using_ipsets;
|
|
|
cead2e |
char vrrp_ipset_address[IPSET_MAXNAMELEN];
|
|
|
cead2e |
diff --git a/keepalived/include/vrrp.h b/keepalived/include/vrrp.h
|
|
|
cead2e |
index 6e874689..ab757277 100644
|
|
|
cead2e |
--- a/keepalived/include/vrrp.h
|
|
|
cead2e |
+++ b/keepalived/include/vrrp.h
|
|
|
cead2e |
@@ -313,6 +313,10 @@ typedef struct _vrrp_t {
|
|
|
cead2e |
|
|
|
cead2e |
#define VRRP_ISUP(V) (VRRP_IF_ISUP(V) && VRRP_SCRIPT_ISUP(V))
|
|
|
cead2e |
|
|
|
cead2e |
+/* Global variables */
|
|
|
cead2e |
+extern bool block_ipv4;
|
|
|
cead2e |
+extern bool block_ipv6;
|
|
|
cead2e |
+
|
|
|
cead2e |
/* prototypes */
|
|
|
cead2e |
extern vrrphdr_t *vrrp_get_header(sa_family_t, char *, unsigned *);
|
|
|
cead2e |
extern int open_vrrp_send_socket(sa_family_t, int, ifindex_t, bool);
|
|
|
cead2e |
@@ -327,6 +331,7 @@ extern void vrrp_state_backup(vrrp_t *, char *, ssize_t);
|
|
|
cead2e |
extern void vrrp_state_goto_master(vrrp_t *);
|
|
|
cead2e |
extern void vrrp_state_leave_master(vrrp_t *);
|
|
|
cead2e |
extern bool vrrp_complete_init(void);
|
|
|
cead2e |
+extern void vrrp_restore_interfaces_startup(void);
|
|
|
cead2e |
extern void restore_vrrp_interfaces(void);
|
|
|
cead2e |
extern void shutdown_vrrp_instances(void);
|
|
|
cead2e |
extern void clear_diff_vrrp(void);
|
|
|
cead2e |
diff --git a/keepalived/include/vrrp_ipset.h b/keepalived/include/vrrp_ipset.h
|
|
|
cead2e |
index 9ee1095a..6cc320ef 100644
|
|
|
cead2e |
--- a/keepalived/include/vrrp_ipset.h
|
|
|
cead2e |
+++ b/keepalived/include/vrrp_ipset.h
|
|
|
cead2e |
@@ -27,8 +27,8 @@
|
|
|
cead2e |
#include <libipset/session.h>
|
|
|
cead2e |
#include "vrrp_ipaddress.h"
|
|
|
cead2e |
|
|
|
cead2e |
-int add_ipsets(bool);
|
|
|
cead2e |
-int remove_ipsets(void);
|
|
|
cead2e |
+bool add_ipsets(bool);
|
|
|
cead2e |
+bool remove_ipsets(void);
|
|
|
cead2e |
bool has_ipset_setname(struct ipset_session*, const char *);
|
|
|
cead2e |
bool ipset_init(void);
|
|
|
cead2e |
struct ipset_session* ipset_session_start(void);
|
|
|
cead2e |
diff --git a/keepalived/include/vrrp_iptables.h b/keepalived/include/vrrp_iptables.h
|
|
|
cead2e |
index 2a7681b3..dbbd6fe7 100644
|
|
|
cead2e |
--- a/keepalived/include/vrrp_iptables.h
|
|
|
cead2e |
+++ b/keepalived/include/vrrp_iptables.h
|
|
|
cead2e |
@@ -37,12 +37,11 @@ struct ipt_handle;
|
|
|
cead2e |
#define IPTABLES_MAX_TRIES 3 /* How many times to try adding/deleting when get EAGAIN */
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
-extern bool using_libiptc; /* Set if using libiptc - for dynamic linking */
|
|
|
cead2e |
+extern bool using_libip4tc; /* Set if using lib4iptc - for dynamic linking */
|
|
|
cead2e |
+extern bool using_libip6tc; /* Set if using lib4iptc - for dynamic linking */
|
|
|
cead2e |
#endif
|
|
|
cead2e |
-extern bool use_ip4tables; /* Set if using iptables */
|
|
|
cead2e |
-extern bool use_ip6tables; /* Set if using ip6tables */
|
|
|
cead2e |
|
|
|
cead2e |
-bool iptables_init_lib(void);
|
|
|
cead2e |
+void iptables_init_lib(void);
|
|
|
cead2e |
void iptables_fini(void);
|
|
|
cead2e |
void iptables_startup(bool);
|
|
|
cead2e |
void iptables_cleanup(void);
|
|
|
cead2e |
diff --git a/keepalived/include/vrrp_iptables_calls.h b/keepalived/include/vrrp_iptables_calls.h
|
|
|
cead2e |
index 34052fac..ef4e0183 100644
|
|
|
cead2e |
--- a/keepalived/include/vrrp_iptables_calls.h
|
|
|
cead2e |
+++ b/keepalived/include/vrrp_iptables_calls.h
|
|
|
cead2e |
@@ -34,7 +34,6 @@
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
-extern bool xtables_load(void);
|
|
|
cead2e |
extern void xtables_unload(void);
|
|
|
cead2e |
#endif
|
|
|
cead2e |
extern bool load_xtables_module(const char *, const char *);
|
|
|
cead2e |
@@ -50,6 +49,7 @@ extern int ip6tables_is_chain(struct ip6tc_handle* handle, const char* chain_nam
|
|
|
cead2e |
extern int ip6tables_process_entry( struct ip6tc_handle* handle, const char* chain_name, unsigned int rulenum, const char* target_name, const ip_address_t* src_ip_address, const ip_address_t* dst_ip_address, const char* in_iface, const char* out_iface, uint16_t protocol, uint8_t type, int cmd, bool force);
|
|
|
cead2e |
extern int ip4tables_add_rules(struct iptc_handle* handle, const char* chain_name, unsigned int rulenum, uint8_t dim, uint8_t src_dst, const char* target_name, const char* set_name, uint16_t protocol, uint8_t param, int cmd, bool ignore_errors);
|
|
|
cead2e |
extern int ip6tables_add_rules(struct ip6tc_handle* handle, const char* chain_name, unsigned int rulenum, uint8_t dim, uint8_t src_dst, const char* target_name, const char* set_name, uint16_t protocol, uint8_t param, int cmd, bool ignore_errors);
|
|
|
cead2e |
+extern void check_chains_exist_lib(void);
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
extern bool iptables_lib_init(void);
|
|
|
cead2e |
#endif
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c
|
|
|
cead2e |
index 3d2bfe41..38895af8 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp.c
|
|
|
cead2e |
@@ -72,6 +72,10 @@
|
|
|
cead2e |
#include <netinet/ip6.h>
|
|
|
cead2e |
#include <stdint.h>
|
|
|
cead2e |
|
|
|
cead2e |
+/* Set if need to block ip addresses and are able to do so */
|
|
|
cead2e |
+bool block_ipv4;
|
|
|
cead2e |
+bool block_ipv6;
|
|
|
cead2e |
+
|
|
|
cead2e |
/* add/remove Virtual IP addresses */
|
|
|
cead2e |
static bool
|
|
|
cead2e |
vrrp_handle_ipaddress(vrrp_t * vrrp, int cmd, int type)
|
|
|
cead2e |
@@ -124,7 +128,11 @@ vrrp_handle_accept_mode(vrrp_t *vrrp, int cmd, bool force)
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
do {
|
|
|
cead2e |
- h = iptables_open();
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if ((vrrp->family == AF_INET && using_libip4tc) ||
|
|
|
cead2e |
+ (vrrp->family == AF_INET6 && using_libip6tc))
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ h = iptables_open();
|
|
|
cead2e |
#endif
|
|
|
cead2e |
/* As accept is false, add iptable rule to drop packets destinated to VIPs and eVIPs */
|
|
|
cead2e |
if (!LIST_ISEMPTY(vrrp->vip))
|
|
|
cead2e |
@@ -132,7 +140,10 @@ vrrp_handle_accept_mode(vrrp_t *vrrp, int cmd, bool force)
|
|
|
cead2e |
if (!LIST_ISEMPTY(vrrp->evip))
|
|
|
cead2e |
handle_iptable_rule_to_iplist(h, vrrp->evip, cmd, force);
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
- res = iptables_close(h);
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (h)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ res = iptables_close(h);
|
|
|
cead2e |
} while (res == EAGAIN && ++tries < IPTABLES_MAX_TRIES);
|
|
|
cead2e |
#endif
|
|
|
cead2e |
vrrp->iptable_rules_set = (cmd == IPADDRESS_ADD);
|
|
|
cead2e |
@@ -2363,10 +2374,12 @@ vrrp_complete_instance(vrrp_t * vrrp)
|
|
|
cead2e |
if (vrrp->base_priority != VRRP_PRIO_OWNER && !vrrp->accept) {
|
|
|
cead2e |
//TODO = we have a problem since SNMP may change accept mode
|
|
|
cead2e |
//it can also change priority
|
|
|
cead2e |
- if (vrrp->saddr.ss_family == AF_INET)
|
|
|
cead2e |
- global_data->block_ipv4 = true;
|
|
|
cead2e |
+ if (!global_data->vrrp_iptables_inchain[0])
|
|
|
cead2e |
+ log_message(LOG_INFO, "(%s): Unable to set no_accept mode since iptables chain name unset", vrrp->iname);
|
|
|
cead2e |
+ else if (vrrp->family == AF_INET)
|
|
|
cead2e |
+ block_ipv4 = true;
|
|
|
cead2e |
else
|
|
|
cead2e |
- global_data->block_ipv6 = true;
|
|
|
cead2e |
+ block_ipv6 = true;
|
|
|
cead2e |
}
|
|
|
cead2e |
if (!LIST_ISEMPTY(vrrp->vip)) {
|
|
|
cead2e |
for (e = LIST_HEAD(vrrp->vip); e; ELEMENT_NEXT(e)) {
|
|
|
cead2e |
@@ -2390,7 +2403,6 @@ vrrp_complete_instance(vrrp_t * vrrp)
|
|
|
cead2e |
if (!reload && interface_already_existed) {
|
|
|
cead2e |
// TODO - consider reload
|
|
|
cead2e |
vrrp->vipset = true; /* Set to force address removal */
|
|
|
cead2e |
- vrrp_restore_interface(vrrp, false, true);
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
/* See if we need to set promote_secondaries */
|
|
|
cead2e |
@@ -2452,12 +2464,6 @@ vrrp_complete_init(void)
|
|
|
cead2e |
if (global_data->vrrp_garp_interval || global_data->vrrp_gna_interval)
|
|
|
cead2e |
set_default_garp_delay();
|
|
|
cead2e |
|
|
|
cead2e |
-#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
- /* Make sure we don't have any old iptables/ipsets settings left around */
|
|
|
cead2e |
- if (!reload)
|
|
|
cead2e |
- iptables_cleanup();
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
-
|
|
|
cead2e |
/* Mark any scripts as insecure */
|
|
|
cead2e |
check_vrrp_script_security();
|
|
|
cead2e |
|
|
|
cead2e |
@@ -2623,6 +2629,18 @@ vrrp_complete_init(void)
|
|
|
cead2e |
return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
+void vrrp_restore_interfaces_startup(void)
|
|
|
cead2e |
+{
|
|
|
cead2e |
+ element e;
|
|
|
cead2e |
+ vrrp_t *vrrp;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ for (e = LIST_HEAD(vrrp_data->vrrp); e; ELEMENT_NEXT(e)) {
|
|
|
cead2e |
+ vrrp = ELEMENT_DATA(e);
|
|
|
cead2e |
+ if (vrrp->vipset)
|
|
|
cead2e |
+ vrrp_restore_interface(vrrp, false, true);
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+}
|
|
|
cead2e |
+
|
|
|
cead2e |
/* Try to find a VRRP instance */
|
|
|
cead2e |
static vrrp_t *
|
|
|
cead2e |
vrrp_exist(vrrp_t *old_vrrp)
|
|
|
cead2e |
@@ -2690,12 +2708,19 @@ clear_diff_vrrp_vip(vrrp_t *old_vrrp, vrrp_t *vrrp)
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
do {
|
|
|
cead2e |
- h = iptables_open();
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if ((vrrp->family == AF_INET && using_libip4tc) ||
|
|
|
cead2e |
+ (vrrp->family == AF_INET6 && using_libip6tc))
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ h = iptables_open();
|
|
|
cead2e |
#endif
|
|
|
cead2e |
clear_diff_vrrp_vip_list(vrrp, h, old_vrrp->vip, vrrp->vip);
|
|
|
cead2e |
clear_diff_vrrp_vip_list(vrrp, h, old_vrrp->evip, vrrp->evip);
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
- res = iptables_close(h);
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (h)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ res = iptables_close(h);
|
|
|
cead2e |
} while (res == EAGAIN && ++tries < IPTABLES_MAX_TRIES);
|
|
|
cead2e |
#endif
|
|
|
cead2e |
}
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp_daemon.c b/keepalived/vrrp/vrrp_daemon.c
|
|
|
cead2e |
index 1c2f9e89..1e9282a7 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp_daemon.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp_daemon.c
|
|
|
cead2e |
@@ -202,8 +202,6 @@ start_vrrp(void)
|
|
|
cead2e |
if (global_data->vrrp_no_swap)
|
|
|
cead2e |
set_process_dont_swap(4096); /* guess a stack size to reserve */
|
|
|
cead2e |
|
|
|
cead2e |
- iptables_init();
|
|
|
cead2e |
-
|
|
|
cead2e |
#ifdef _WITH_SNMP_
|
|
|
cead2e |
if (!reload && (global_data->enable_snmp_keepalived || global_data->enable_snmp_rfcv2 || global_data->enable_snmp_rfcv3)) {
|
|
|
cead2e |
vrrp_snmp_agent_init(global_data->snmp_socket);
|
|
|
cead2e |
@@ -266,10 +264,21 @@ start_vrrp(void)
|
|
|
cead2e |
return;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
+ /* We need to delay the init of iptables to after vrrp_complete_init()
|
|
|
cead2e |
+ * has been called so we know whether we want IPv4 and/or IPv6 */
|
|
|
cead2e |
+ iptables_init();
|
|
|
cead2e |
+
|
|
|
cead2e |
+ /* Make sure we don't have any old iptables/ipsets settings left around */
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
+ if (!reload)
|
|
|
cead2e |
+ iptables_cleanup();
|
|
|
cead2e |
+
|
|
|
cead2e |
iptables_startup(reload);
|
|
|
cead2e |
#endif
|
|
|
cead2e |
|
|
|
cead2e |
+ if (!reload)
|
|
|
cead2e |
+ vrrp_restore_interfaces_startup();
|
|
|
cead2e |
+
|
|
|
cead2e |
/* clear_diff_vrrp must be called after vrrp_complete_init, since the latter
|
|
|
cead2e |
* sets ifa_index on the addresses, which is used for the address comparison */
|
|
|
cead2e |
if (reload)
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp_ipaddress.c b/keepalived/vrrp/vrrp_ipaddress.c
|
|
|
cead2e |
index eb332e72..c72ea736 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp_ipaddress.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp_ipaddress.c
|
|
|
cead2e |
@@ -27,6 +27,7 @@
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
#include "vrrp_iptables.h"
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+#include "vrrp.h"
|
|
|
cead2e |
#include "keepalived_netlink.h"
|
|
|
cead2e |
#include "vrrp_data.h"
|
|
|
cead2e |
#include "logger.h"
|
|
|
cead2e |
@@ -38,11 +39,16 @@
|
|
|
cead2e |
#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
#include "utils.h"
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+#include "vrrp_iptables.h"
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
|
|
|
cead2e |
#define INFINITY_LIFE_TIME 0xFFFFFFFF
|
|
|
cead2e |
|
|
|
cead2e |
-bool iptables_cmd_available = true;
|
|
|
cead2e |
-bool ip6tables_cmd_available = true;
|
|
|
cead2e |
+#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+static bool iptables_cmd_available;
|
|
|
cead2e |
+static bool ip6tables_cmd_available;
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
|
|
|
cead2e |
char *
|
|
|
cead2e |
ipaddresstos(char *buf, ip_address_t *ipaddress)
|
|
|
cead2e |
@@ -250,9 +256,6 @@ handle_iptable_rule_to_vip_cmd(ip_address_t *ipaddress, int cmd, bool force)
|
|
|
cead2e |
char *addr_str;
|
|
|
cead2e |
char *ifname = NULL;
|
|
|
cead2e |
|
|
|
cead2e |
- if (global_data->vrrp_iptables_inchain[0] == '\0')
|
|
|
cead2e |
- return;
|
|
|
cead2e |
-
|
|
|
cead2e |
if (IP_IS6(ipaddress)) {
|
|
|
cead2e |
if (!ip6tables_cmd_available)
|
|
|
cead2e |
return;
|
|
|
cead2e |
@@ -316,9 +319,18 @@ handle_iptable_rule_to_vip(ip_address_t *ipaddr, int cmd,
|
|
|
cead2e |
#endif
|
|
|
cead2e |
bool force)
|
|
|
cead2e |
{
|
|
|
cead2e |
+ if (IP_IS6(ipaddr)) {
|
|
|
cead2e |
+ if (!block_ipv6)
|
|
|
cead2e |
+ return;
|
|
|
cead2e |
+ } else {
|
|
|
cead2e |
+ if (!block_ipv4)
|
|
|
cead2e |
+ return;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
- if (using_libiptc)
|
|
|
cead2e |
+ if ((IP_IS6(ipaddr) && using_libip6tc) ||
|
|
|
cead2e |
+ (!IP_IS6(ipaddr) && using_libip4tc))
|
|
|
cead2e |
#endif
|
|
|
cead2e |
{
|
|
|
cead2e |
handle_iptable_rule_to_vip_lib(ipaddr, cmd, h, force);
|
|
|
cead2e |
@@ -612,31 +624,122 @@ clear_diff_saddresses(void)
|
|
|
cead2e |
clear_diff_address(NULL, old_vrrp_data->static_addresses, vrrp_data->static_addresses);
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
+static void
|
|
|
cead2e |
+check_chains_exist(void)
|
|
|
cead2e |
+{
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (using_libip4tc || using_libip6tc)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ check_chains_exist_lib();
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+
|
|
|
cead2e |
+#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ char *argv[4];
|
|
|
cead2e |
+
|
|
|
cead2e |
+ argv[1] = "-nL";
|
|
|
cead2e |
+ argv[2] = global_data->vrrp_iptables_inchain;
|
|
|
cead2e |
+ argv[3] = NULL;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (block_ipv4)
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (!using_libip4tc)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ argv[0] = "iptables";
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (fork_exec(argv) < 0) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "iptables chain %s does not exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ else if (global_data->vrrp_iptables_outchain[0]) {
|
|
|
cead2e |
+ argv[2] = global_data->vrrp_iptables_outchain;
|
|
|
cead2e |
+ if (fork_exec(argv) < 0) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "iptables chain %s does not exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (block_ipv6)
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (!using_libip6tc)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ argv[0] = "ip6tables";
|
|
|
cead2e |
+ argv[2] = global_data->vrrp_iptables_inchain;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (fork_exec(argv) < 0) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "ip6tables chain %s does not exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ else if (global_data->vrrp_iptables_outchain[0]) {
|
|
|
cead2e |
+ argv[2] = global_data->vrrp_iptables_outchain;
|
|
|
cead2e |
+ if (fork_exec(argv) < 0) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "ip6tables chain %s does not exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+}
|
|
|
cead2e |
+
|
|
|
cead2e |
void
|
|
|
cead2e |
iptables_init(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
-#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
- if (iptables_init_lib())
|
|
|
cead2e |
+ if (!block_ipv4 && !block_ipv6) {
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
+ global_data->using_ipsets = false;
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
return;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
+ iptables_init_lib();
|
|
|
cead2e |
#endif
|
|
|
cead2e |
|
|
|
cead2e |
#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
char *argv[3];
|
|
|
cead2e |
|
|
|
cead2e |
- /* We can't use libiptc, so check iptables command available */
|
|
|
cead2e |
- argv[0] = "iptables";
|
|
|
cead2e |
+ /* If can't use libiptc, check iptables command available */
|
|
|
cead2e |
argv[1] = "-V";
|
|
|
cead2e |
argv[2] = NULL;
|
|
|
cead2e |
|
|
|
cead2e |
- if (fork_exec(argv) < 0) {
|
|
|
cead2e |
- log_message(LOG_INFO, "iptables command not available - can't filter IPv4 VIP address destinations");
|
|
|
cead2e |
- iptables_cmd_available = false;
|
|
|
cead2e |
+ if (block_ipv4
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ && !using_libip4tc
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ )
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ argv[0] = "iptables";
|
|
|
cead2e |
+ if (!(iptables_cmd_available = (fork_exec(argv) >= 0))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "iptables command not available - can't filter IPv4 VIP address destinations");
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- argv[0] = "ip6tables";
|
|
|
cead2e |
- if (fork_exec(argv) < 0) {
|
|
|
cead2e |
- log_message(LOG_INFO, "ip6tables command not available - can't filter IPv6 VIP address destinations");
|
|
|
cead2e |
- ip6tables_cmd_available = false;
|
|
|
cead2e |
+ if (block_ipv6
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ && !using_libip6tc
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ )
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ argv[0] = "ip6tables";
|
|
|
cead2e |
+ if (!(ip6tables_cmd_available = (fork_exec(argv) >= 0))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "ip6tables command not available - can't filter IPv6 VIP address destinations");
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
}
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (block_ipv4 || block_ipv6)
|
|
|
cead2e |
+ check_chains_exist();
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
+ else
|
|
|
cead2e |
+ global_data->using_ipsets = false;
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
}
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp_ipset.c b/keepalived/vrrp/vrrp_ipset.c
|
|
|
cead2e |
index 194809f0..1c3e4990 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp_ipset.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp_ipset.c
|
|
|
cead2e |
@@ -38,12 +38,14 @@
|
|
|
cead2e |
#include <linux/types.h> /* For __beXX types in userland */
|
|
|
cead2e |
#include <linux/netfilter.h> /* For nf_inet_addr */
|
|
|
cead2e |
#include <stdint.h>
|
|
|
cead2e |
+#include <stdio.h>
|
|
|
cead2e |
|
|
|
cead2e |
#include "logger.h"
|
|
|
cead2e |
#include "global_data.h"
|
|
|
cead2e |
#include "vrrp_iptables.h"
|
|
|
cead2e |
#include "vrrp_ipset.h"
|
|
|
cead2e |
#include "vrrp_ipaddress.h"
|
|
|
cead2e |
+#include "vrrp.h"
|
|
|
cead2e |
#include "main.h"
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _LIBIPSET_DYNAMIC_
|
|
|
cead2e |
@@ -146,7 +148,7 @@ has_ipset_setname(struct ipset_session* session, const char *setname)
|
|
|
cead2e |
return ipset_cmd1(session, IPSET_CMD_HEADER, 0) == 0;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
-static int create_sets(const char* addr4, const char* addr6, const char* addr_if6, bool reload)
|
|
|
cead2e |
+static bool create_sets(const char* addr4, const char* addr6, const char* addr_if6, bool reload)
|
|
|
cead2e |
{
|
|
|
cead2e |
struct ipset_session *session;
|
|
|
cead2e |
|
|
|
cead2e |
@@ -161,12 +163,12 @@ static int create_sets(const char* addr4, const char* addr6, const char* addr_if
|
|
|
cead2e |
if (!reload)
|
|
|
cead2e |
ipset_envopt_parse(session, IPSET_ENV_EXIST, NULL);
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip4tables) {
|
|
|
cead2e |
+ if (block_ipv4) {
|
|
|
cead2e |
if (!reload || !has_ipset_setname(session, addr4))
|
|
|
cead2e |
ipset_create(session, addr4, "hash:ip", NFPROTO_IPV4);
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip6tables) {
|
|
|
cead2e |
+ if (block_ipv6) {
|
|
|
cead2e |
if (!reload || !has_ipset_setname(session, addr6))
|
|
|
cead2e |
ipset_create(session, addr6, "hash:ip", NFPROTO_IPV6);
|
|
|
cead2e |
if (!reload || !has_ipset_setname(session, addr_if6)) {
|
|
|
cead2e |
@@ -184,6 +186,30 @@ static int create_sets(const char* addr4, const char* addr6, const char* addr_if
|
|
|
cead2e |
return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
+static
|
|
|
cead2e |
+bool set_match_loaded(void)
|
|
|
cead2e |
+{
|
|
|
cead2e |
+ char buf[XT_FUNCTION_MAXNAMELEN+1];
|
|
|
cead2e |
+ FILE *fp;
|
|
|
cead2e |
+ bool found = false;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ fp = fopen( "/proc/net/ip_tables_matches", "r");
|
|
|
cead2e |
+ if (!fp)
|
|
|
cead2e |
+ return false;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ while (fgets(buf, sizeof(buf), fp)) {
|
|
|
cead2e |
+ if ((buf[3] == '\0' || buf[3] == '\n') &&
|
|
|
cead2e |
+ !strncmp(buf, "set", 3)) {
|
|
|
cead2e |
+ found = true;
|
|
|
cead2e |
+ break;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
+ fclose(fp);
|
|
|
cead2e |
+
|
|
|
cead2e |
+ return found;
|
|
|
cead2e |
+}
|
|
|
cead2e |
+
|
|
|
cead2e |
bool ipset_init(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
#ifdef _LIBIPSET_DYNAMIC_
|
|
|
cead2e |
@@ -213,44 +239,47 @@ bool ipset_init(void)
|
|
|
cead2e |
return false;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- int err = false;
|
|
|
cead2e |
- if (!(ipset_session_init_addr = dlsym(libipset_handle, "ipset_session_init"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_session_init"); err = true;}
|
|
|
cead2e |
- if (!(ipset_session_fini_addr = dlsym(libipset_handle, "ipset_session_fini"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_session_fini"); err = true;}
|
|
|
cead2e |
- if (!(ipset_session_data_addr = dlsym(libipset_handle,"ipset_session_data"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_session_data"); err = true;}
|
|
|
cead2e |
- if (!(ipset_session_error_addr = dlsym(libipset_handle,"ipset_session_error"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_session_error"); err = true;}
|
|
|
cead2e |
- if (!(ipset_envopt_parse_addr = dlsym(libipset_handle,"ipset_envopt_parse"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_envopt_parse"); err = true;}
|
|
|
cead2e |
- if (!(ipset_type_get_addr = dlsym(libipset_handle,"ipset_type_get"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_type_get"); err = true;}
|
|
|
cead2e |
- if (!(ipset_data_set_addr = dlsym(libipset_handle,"ipset_data_set"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_data_set"); err = true;}
|
|
|
cead2e |
- if (!(ipset_cmd_addr = dlsym(libipset_handle,"ipset_cmd"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_cmd"); err = true;}
|
|
|
cead2e |
- if (!(ipset_load_types_addr = dlsym(libipset_handle,"ipset_load_types"))) {log_message(LOG_INFO, "Failed to dynamic link ipset_load_types"); err = true;}
|
|
|
cead2e |
- if (err) {
|
|
|
cead2e |
- log_message(LOG_INFO, "Failed to dynamic link an ipset function");
|
|
|
cead2e |
+ if (!(ipset_session_init_addr = dlsym(libipset_handle, "ipset_session_init")) ||
|
|
|
cead2e |
+ !(ipset_session_fini_addr = dlsym(libipset_handle, "ipset_session_fini")) ||
|
|
|
cead2e |
+ !(ipset_session_data_addr = dlsym(libipset_handle,"ipset_session_data")) ||
|
|
|
cead2e |
+ !(ipset_session_error_addr = dlsym(libipset_handle,"ipset_session_error")) ||
|
|
|
cead2e |
+ !(ipset_envopt_parse_addr = dlsym(libipset_handle,"ipset_envopt_parse")) ||
|
|
|
cead2e |
+ !(ipset_type_get_addr = dlsym(libipset_handle,"ipset_type_get")) ||
|
|
|
cead2e |
+ !(ipset_data_set_addr = dlsym(libipset_handle,"ipset_data_set")) ||
|
|
|
cead2e |
+ !(ipset_cmd_addr = dlsym(libipset_handle,"ipset_cmd")) ||
|
|
|
cead2e |
+ !(ipset_load_types_addr = dlsym(libipset_handle,"ipset_load_types"))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Failed to dynamic link an ipset function - %s", dlerror());
|
|
|
cead2e |
return false;
|
|
|
cead2e |
}
|
|
|
cead2e |
#endif
|
|
|
cead2e |
|
|
|
cead2e |
ipset_load_types();
|
|
|
cead2e |
|
|
|
cead2e |
- if (!load_xtables_module("xt_set", "ipsets"))
|
|
|
cead2e |
+ if (!set_match_loaded() && !load_xtables_module("xt_set", "ipsets")) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Unable to load module xt_set - not using ipsets");
|
|
|
cead2e |
return false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
|
|
|
cead2e |
return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
-int remove_ipsets(void)
|
|
|
cead2e |
+bool remove_ipsets(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
struct ipset_session *session;
|
|
|
cead2e |
|
|
|
cead2e |
+ if (!global_data->using_ipsets)
|
|
|
cead2e |
+ return true;
|
|
|
cead2e |
+
|
|
|
cead2e |
session = ipset_session_init(printf);
|
|
|
cead2e |
if (!session) {
|
|
|
cead2e |
log_message(LOG_INFO, "Cannot initialize ipset session.");
|
|
|
cead2e |
return false;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip4tables)
|
|
|
cead2e |
+ if (block_ipv4)
|
|
|
cead2e |
ipset_destroy(session, global_data->vrrp_ipset_address);
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip6tables) {
|
|
|
cead2e |
+ if (block_ipv6) {
|
|
|
cead2e |
ipset_destroy(session, global_data->vrrp_ipset_address6);
|
|
|
cead2e |
ipset_destroy(session, global_data->vrrp_ipset_address_iface6);
|
|
|
cead2e |
}
|
|
|
cead2e |
@@ -260,7 +289,7 @@ int remove_ipsets(void)
|
|
|
cead2e |
return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
-int add_ipsets(bool reload)
|
|
|
cead2e |
+bool add_ipsets(bool reload)
|
|
|
cead2e |
{
|
|
|
cead2e |
return create_sets(global_data->vrrp_ipset_address, global_data->vrrp_ipset_address6, global_data->vrrp_ipset_address_iface6, reload);
|
|
|
cead2e |
}
|
|
|
cead2e |
@@ -281,12 +310,12 @@ void ipset_entry(struct ipset_session* session, int cmd, const ip_address_t* add
|
|
|
cead2e |
char *iface = NULL;
|
|
|
cead2e |
|
|
|
cead2e |
if (addr->ifa.ifa_family == AF_INET) {
|
|
|
cead2e |
- if (!use_ip4tables)
|
|
|
cead2e |
+ if (!block_ipv4)
|
|
|
cead2e |
return;
|
|
|
cead2e |
set = global_data->vrrp_ipset_address;
|
|
|
cead2e |
}
|
|
|
cead2e |
else if (IN6_IS_ADDR_LINKLOCAL(&addr->u.sin6_addr)) {
|
|
|
cead2e |
- if (!use_ip6tables)
|
|
|
cead2e |
+ if (!block_ipv6)
|
|
|
cead2e |
return;
|
|
|
cead2e |
|
|
|
cead2e |
set = global_data->vrrp_ipset_address_iface6;
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp_iptables.c b/keepalived/vrrp/vrrp_iptables.c
|
|
|
cead2e |
index 2c218cac..60ff6c8c 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp_iptables.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp_iptables.c
|
|
|
cead2e |
@@ -59,6 +59,10 @@
|
|
|
cead2e |
#include <xtables.h>
|
|
|
cead2e |
#include <libipset/linux_ip_set.h>
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+#include <sys/stat.h>
|
|
|
cead2e |
+#include <sys/vfs.h>
|
|
|
cead2e |
+#include <linux/magic.h>
|
|
|
cead2e |
+#include <stdbool.h>
|
|
|
cead2e |
|
|
|
cead2e |
#include "vrrp_iptables.h"
|
|
|
cead2e |
#include "vrrp_iptables_calls.h"
|
|
|
cead2e |
@@ -81,10 +85,9 @@ struct ipt_handle {
|
|
|
cead2e |
|
|
|
cead2e |
/* If the chains don't exist, or modules not loaded, we can't use iptables/ip6tables */
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
-bool using_libiptc = true;
|
|
|
cead2e |
+bool using_libip4tc = false;
|
|
|
cead2e |
+bool using_libip6tc = false;
|
|
|
cead2e |
#endif
|
|
|
cead2e |
-bool use_ip4tables = true;
|
|
|
cead2e |
-bool use_ip6tables = true;
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
static
|
|
|
cead2e |
@@ -105,10 +108,13 @@ void add_del_rules(int cmd, bool ignore_errors)
|
|
|
cead2e |
struct iptc_handle *h4;
|
|
|
cead2e |
struct ip6tc_handle *h6;
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip4tables &&
|
|
|
cead2e |
- global_data->block_ipv4 &&
|
|
|
cead2e |
+ if (block_ipv4 &&
|
|
|
cead2e |
(global_data->vrrp_iptables_inchain[0] ||
|
|
|
cead2e |
- global_data->vrrp_iptables_outchain[0])) {
|
|
|
cead2e |
+ global_data->vrrp_iptables_outchain[0])
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ && using_libip4tc
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ ) {
|
|
|
cead2e |
if ((h4 = ip4tables_open("filter"))) {
|
|
|
cead2e |
if (global_data->vrrp_iptables_inchain[0])
|
|
|
cead2e |
ip4tables_add_rules(h4, global_data->vrrp_iptables_inchain, APPEND_RULE, IPSET_DIM_ONE, 0, XTC_LABEL_DROP, global_data->vrrp_ipset_address, IPPROTO_NONE, 0, cmd, ignore_errors);
|
|
|
cead2e |
@@ -118,10 +124,13 @@ void add_del_rules(int cmd, bool ignore_errors)
|
|
|
cead2e |
}
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- if (use_ip6tables &&
|
|
|
cead2e |
- global_data->block_ipv6 &&
|
|
|
cead2e |
+ if (block_ipv6 &&
|
|
|
cead2e |
(global_data->vrrp_iptables_inchain[0] ||
|
|
|
cead2e |
- global_data->vrrp_iptables_outchain[0])) {
|
|
|
cead2e |
+ global_data->vrrp_iptables_outchain[0])
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ && using_libip6tc
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ ) {
|
|
|
cead2e |
if ((h6 = ip6tables_open("filter"))) {
|
|
|
cead2e |
if (global_data->vrrp_iptables_inchain[0]) {
|
|
|
cead2e |
#ifdef HAVE_IPSET_ATTR_IFACE
|
|
|
cead2e |
@@ -185,58 +194,64 @@ int iptables_close(struct ipt_handle* h)
|
|
|
cead2e |
return res;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
-static void check_chains_exist(void)
|
|
|
cead2e |
+void check_chains_exist_lib(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
struct iptc_handle *h4;
|
|
|
cead2e |
struct ip6tc_handle *h6;
|
|
|
cead2e |
|
|
|
cead2e |
- if (global_data->block_ipv4) {
|
|
|
cead2e |
- h4 = ip4tables_open("filter");
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (!h4) {
|
|
|
cead2e |
- log_message(LOG_INFO, "WARNING, ip_tables module not installed - can't filter IPv4 addresses");
|
|
|
cead2e |
- use_ip4tables = false;
|
|
|
cead2e |
- } else {
|
|
|
cead2e |
- if (global_data->vrrp_iptables_inchain[0] &&
|
|
|
cead2e |
- !ip4tables_is_chain(h4, global_data->vrrp_iptables_inchain)) {
|
|
|
cead2e |
- log_message(LOG_INFO, "iptables chain %s doesn't exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
- use_ip4tables = false;
|
|
|
cead2e |
- }
|
|
|
cead2e |
- if (global_data->vrrp_iptables_outchain[0] &&
|
|
|
cead2e |
- !ip4tables_is_chain(h4, global_data->vrrp_iptables_outchain)) {
|
|
|
cead2e |
- log_message(LOG_INFO, "iptables chain %s doesn't exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
- use_ip4tables = false;
|
|
|
cead2e |
+ if (block_ipv4) {
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (using_libip4tc)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ h4 = ip4tables_open("filter");
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (!h4) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "WARNING, ip_tables module not installed - can't filter IPv4 addresses");
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ } else {
|
|
|
cead2e |
+ if (global_data->vrrp_iptables_inchain[0] &&
|
|
|
cead2e |
+ !ip4tables_is_chain(h4, global_data->vrrp_iptables_inchain)) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "iptables chain %s doesn't exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ if (global_data->vrrp_iptables_outchain[0] &&
|
|
|
cead2e |
+ !ip4tables_is_chain(h4, global_data->vrrp_iptables_outchain)) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "iptables chain %s doesn't exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
+ ip4tables_close(h4, false);
|
|
|
cead2e |
}
|
|
|
cead2e |
-
|
|
|
cead2e |
- ip4tables_close(h4, false);
|
|
|
cead2e |
}
|
|
|
cead2e |
}
|
|
|
cead2e |
- else
|
|
|
cead2e |
- use_ip4tables = false;
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (global_data->block_ipv6) {
|
|
|
cead2e |
- h6 = ip6tables_open("filter");
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (!h6) {
|
|
|
cead2e |
- log_message(LOG_INFO, "WARNING, ip6_tables module not installed - can't filter IPv6 addresses");
|
|
|
cead2e |
- use_ip6tables = false;
|
|
|
cead2e |
- } else {
|
|
|
cead2e |
- if (global_data->vrrp_iptables_inchain[0] &&
|
|
|
cead2e |
- !ip6tables_is_chain(h6, global_data->vrrp_iptables_inchain)) {
|
|
|
cead2e |
- log_message(LOG_INFO, "ip6tables chain %s doesn't exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
- use_ip6tables = false;
|
|
|
cead2e |
- }
|
|
|
cead2e |
- if (global_data->vrrp_iptables_outchain[0] &&
|
|
|
cead2e |
- !ip6tables_is_chain(h6, global_data->vrrp_iptables_outchain)) {
|
|
|
cead2e |
- log_message(LOG_INFO, "ip6tables chain %s doesn't exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
- use_ip6tables = false;
|
|
|
cead2e |
- }
|
|
|
cead2e |
|
|
|
cead2e |
- ip6tables_close(h6, false);
|
|
|
cead2e |
+ if (block_ipv6) {
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ if (using_libip6tc)
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ h6 = ip6tables_open("filter");
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (!h6) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "WARNING, ip6_tables module not installed - can't filter IPv6 addresses");
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ } else {
|
|
|
cead2e |
+ if (global_data->vrrp_iptables_inchain[0] &&
|
|
|
cead2e |
+ !ip6tables_is_chain(h6, global_data->vrrp_iptables_inchain)) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "ip6tables chain %s doesn't exist", global_data->vrrp_iptables_inchain);
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ if (global_data->vrrp_iptables_outchain[0] &&
|
|
|
cead2e |
+ !ip6tables_is_chain(h6, global_data->vrrp_iptables_outchain)) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "ip6tables chain %s doesn't exist", global_data->vrrp_iptables_outchain);
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+
|
|
|
cead2e |
+ ip6tables_close(h6, false);
|
|
|
cead2e |
+ }
|
|
|
cead2e |
}
|
|
|
cead2e |
}
|
|
|
cead2e |
- else
|
|
|
cead2e |
- use_ip6tables = false;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
static int iptables_entry(struct ipt_handle* h, const char* chain_name, unsigned int rulenum, char* target_name, const ip_address_t* src_ip_address, const ip_address_t* dst_ip_address, const char* in_iface, const char* out_iface, uint16_t protocol, uint8_t type, int cmd, bool force)
|
|
|
cead2e |
@@ -303,11 +318,8 @@ handle_iptable_rule_to_vip_lib(ip_address_t *ipaddress, int cmd, struct ipt_hand
|
|
|
cead2e |
char *ifname = NULL;
|
|
|
cead2e |
|
|
|
cead2e |
/* If iptables for the address family isn't in use, skip */
|
|
|
cead2e |
- if ((ipaddress->ifa.ifa_family == AF_INET && !use_ip4tables) ||
|
|
|
cead2e |
- (ipaddress->ifa.ifa_family == AF_INET6 && !use_ip6tables))
|
|
|
cead2e |
- return;
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (global_data->vrrp_iptables_inchain[0] == '\0')
|
|
|
cead2e |
+ if ((ipaddress->ifa.ifa_family == AF_INET && !block_ipv4) ||
|
|
|
cead2e |
+ (ipaddress->ifa.ifa_family == AF_INET6 && !block_ipv6))
|
|
|
cead2e |
return;
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
@@ -343,33 +355,28 @@ handle_iptable_rule_to_vip_lib(ip_address_t *ipaddress, int cmd, struct ipt_hand
|
|
|
cead2e |
IPPROTO_NONE, 0, cmd, force);
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
static void
|
|
|
cead2e |
-iptables_remove_structure(
|
|
|
cead2e |
-#ifndef _HAVE_LIBIPSET_
|
|
|
cead2e |
- __attribute__((unused))
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
- bool ignore_errors)
|
|
|
cead2e |
+iptables_remove_structure(bool ignore_errors)
|
|
|
cead2e |
{
|
|
|
cead2e |
-#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
if (global_data->using_ipsets) {
|
|
|
cead2e |
add_del_rules(IPADDRESS_DEL, ignore_errors);
|
|
|
cead2e |
add_del_sets(IPADDRESS_DEL, false);
|
|
|
cead2e |
}
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
}
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
|
|
|
cead2e |
void
|
|
|
cead2e |
-iptables_startup(bool reload)
|
|
|
cead2e |
+iptables_startup(
|
|
|
cead2e |
+#ifndef _HAVE_LIBIPSET_
|
|
|
cead2e |
+ __attribute__((unused))
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+ bool reload)
|
|
|
cead2e |
{
|
|
|
cead2e |
- if (!reload) {
|
|
|
cead2e |
- check_chains_exist();
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
- if (!use_ip4tables && !use_ip6tables)
|
|
|
cead2e |
- global_data->using_ipsets = false;
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
- }
|
|
|
cead2e |
+ if (!block_ipv4 && !block_ipv6)
|
|
|
cead2e |
+ global_data->using_ipsets = false;
|
|
|
cead2e |
|
|
|
cead2e |
-#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
if (global_data->using_ipsets) {
|
|
|
cead2e |
add_del_sets(IPADDRESS_ADD, reload);
|
|
|
cead2e |
add_del_rules(IPADDRESS_ADD, false);
|
|
|
cead2e |
@@ -380,50 +387,94 @@ iptables_startup(bool reload)
|
|
|
cead2e |
void
|
|
|
cead2e |
iptables_cleanup(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
iptables_remove_structure(true);
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+}
|
|
|
cead2e |
+
|
|
|
cead2e |
+/* return true if a given file exists within procfs */
|
|
|
cead2e |
+/* Taken from iptables code */
|
|
|
cead2e |
+static
|
|
|
cead2e |
+bool proc_file_exists(const char *filename)
|
|
|
cead2e |
+{
|
|
|
cead2e |
+ struct stat s;
|
|
|
cead2e |
+ struct statfs f;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ if (lstat(filename, &s))
|
|
|
cead2e |
+ return false;
|
|
|
cead2e |
+ if (!S_ISREG(s.st_mode))
|
|
|
cead2e |
+ return false;
|
|
|
cead2e |
+ if (statfs(filename, &f))
|
|
|
cead2e |
+ return false;
|
|
|
cead2e |
+ if (f.f_type != PROC_SUPER_MAGIC)
|
|
|
cead2e |
+ return false;
|
|
|
cead2e |
+
|
|
|
cead2e |
+ return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
-bool
|
|
|
cead2e |
+void
|
|
|
cead2e |
iptables_init_lib(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
-#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
- xtables_load();
|
|
|
cead2e |
+ if (block_ipv4) {
|
|
|
cead2e |
+ if (!proc_file_exists("/proc/net/ip_tables_names") &&
|
|
|
cead2e |
+ !load_xtables_module("ip_tables", "iptables"))
|
|
|
cead2e |
+#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
+ using_libip4tc = false;
|
|
|
cead2e |
+ else
|
|
|
cead2e |
+ using_libip4tc = true;
|
|
|
cead2e |
+#else
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ block_ipv4 = false;
|
|
|
cead2e |
+ log_message(LOG_INFO, "Unable to load module ip_tables");
|
|
|
cead2e |
+ }
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+ }
|
|
|
cead2e |
|
|
|
cead2e |
+ if (block_ipv6) {
|
|
|
cead2e |
+ if (!proc_file_exists("/proc/net/ip6_tables_names") &&
|
|
|
cead2e |
+ !load_xtables_module("ip6_tables", "ip6tables"))
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
- if (!iptables_lib_init()) {
|
|
|
cead2e |
- using_libiptc = false;
|
|
|
cead2e |
-#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
- xtables_unload();
|
|
|
cead2e |
+ using_libip6tc = false;
|
|
|
cead2e |
+ else
|
|
|
cead2e |
+ using_libip6tc = true;
|
|
|
cead2e |
+#else
|
|
|
cead2e |
+ {
|
|
|
cead2e |
+ block_ipv6 = false;
|
|
|
cead2e |
+ log_message(LOG_INFO, "Unable to load module ip_tables");
|
|
|
cead2e |
+ }
|
|
|
cead2e |
#endif
|
|
|
cead2e |
- return false;
|
|
|
cead2e |
}
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
|
|
|
cead2e |
- if (!load_xtables_module("ip_tables", "iptables")) {
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
- using_libiptc = false;
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
+ if ((!block_ipv4 && !block_ipv6) ||
|
|
|
cead2e |
+ (!using_libip4tc && !using_libip6tc) ||
|
|
|
cead2e |
+ !iptables_lib_init()) {
|
|
|
cead2e |
#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
xtables_unload();
|
|
|
cead2e |
#endif
|
|
|
cead2e |
- return false;
|
|
|
cead2e |
+
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
+ global_data->using_ipsets = false;
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
+
|
|
|
cead2e |
+ return;
|
|
|
cead2e |
}
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
- if (!ipset_init())
|
|
|
cead2e |
+ if (global_data->using_ipsets && !ipset_init())
|
|
|
cead2e |
global_data->using_ipsets = false;
|
|
|
cead2e |
#endif
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
xtables_unload();
|
|
|
cead2e |
#endif
|
|
|
cead2e |
-
|
|
|
cead2e |
- return true;
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
void
|
|
|
cead2e |
iptables_fini(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
iptables_remove_structure(false);
|
|
|
cead2e |
+#endif
|
|
|
cead2e |
}
|
|
|
cead2e |
diff --git a/keepalived/vrrp/vrrp_iptables_calls.c b/keepalived/vrrp/vrrp_iptables_calls.c
|
|
|
cead2e |
index fb5c98df..ff6b7e6e 100644
|
|
|
cead2e |
--- a/keepalived/vrrp/vrrp_iptables_calls.c
|
|
|
cead2e |
+++ b/keepalived/vrrp/vrrp_iptables_calls.c
|
|
|
cead2e |
@@ -37,22 +37,18 @@
|
|
|
cead2e |
#include <xtables.h>
|
|
|
cead2e |
#include <libiptc/libiptc.h>
|
|
|
cead2e |
#include <libiptc/libip6tc.h>
|
|
|
cead2e |
-#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
#include <libipset/linux_ip_set.h>
|
|
|
cead2e |
#if defined XT_SET_H_ADD_IP_SET_H_GUARD
|
|
|
cead2e |
#define _IP_SET_H
|
|
|
cead2e |
#elif defined XT_SET_H_ADD_UAPI_IP_SET_H_GUARD
|
|
|
cead2e |
#define _UAPI_IP_SET_H
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+#ifdef _HAVE_LIBIPSET_
|
|
|
cead2e |
#include <linux/netfilter/xt_set.h>
|
|
|
cead2e |
#endif
|
|
|
cead2e |
#include <unistd.h>
|
|
|
cead2e |
#include <signal.h>
|
|
|
cead2e |
#include <stdint.h>
|
|
|
cead2e |
-#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
-#include <sys/types.h>
|
|
|
cead2e |
-#include <sys/stat.h>
|
|
|
cead2e |
-#endif
|
|
|
cead2e |
|
|
|
cead2e |
#include "vrrp_iptables_calls.h"
|
|
|
cead2e |
#include "memory.h"
|
|
|
cead2e |
@@ -63,6 +59,7 @@
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
#include "global_data.h"
|
|
|
cead2e |
#endif
|
|
|
cead2e |
+#include "vrrp_iptables.h"
|
|
|
cead2e |
|
|
|
cead2e |
/* We sometimes get a resource_busy on iptc_commit. This appears to happen
|
|
|
cead2e |
* when someone else is also updating it.
|
|
|
cead2e |
@@ -406,6 +403,7 @@ int ip6tables_process_entry( struct ip6tc_handle* handle, const char* chain_name
|
|
|
cead2e |
|
|
|
cead2e |
#ifdef _HAVE_LIBIPTC_
|
|
|
cead2e |
#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
+static
|
|
|
cead2e |
bool xtables_load(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
if (libxtables_handle)
|
|
|
cead2e |
@@ -418,7 +416,7 @@ bool xtables_load(void)
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
if (!(xtables_insmod_addr = dlsym(libxtables_handle, "xtables_insmod"))) {
|
|
|
cead2e |
- log_message(LOG_INFO, "Failed to dynamic link xtables_insmod");
|
|
|
cead2e |
+ log_message(LOG_INFO, "Failed to dynamic link xtables_insmod - %s", dlerror());
|
|
|
cead2e |
dlclose(libxtables_handle);
|
|
|
cead2e |
libxtables_handle = NULL;
|
|
|
cead2e |
|
|
|
cead2e |
@@ -438,25 +436,18 @@ void xtables_unload(void)
|
|
|
cead2e |
}
|
|
|
cead2e |
#endif
|
|
|
cead2e |
|
|
|
cead2e |
-bool load_xtables_module(const char *module,
|
|
|
cead2e |
+bool
|
|
|
cead2e |
+load_xtables_module(const char *module,
|
|
|
cead2e |
#ifndef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
- __attribute__((unused))
|
|
|
cead2e |
+ __attribute__((unused))
|
|
|
cead2e |
#endif
|
|
|
cead2e |
- const char *function)
|
|
|
cead2e |
+ const char *function)
|
|
|
cead2e |
{
|
|
|
cead2e |
struct sigaction act, old_act;
|
|
|
cead2e |
bool res = true;
|
|
|
cead2e |
-#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
- struct stat stat_buf;
|
|
|
cead2e |
- char module_path[32] = "/sys/module/";
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (!libxtables_handle) {
|
|
|
cead2e |
- /* See if the module is loaded anyway */
|
|
|
cead2e |
- strcat(module_path, module);
|
|
|
cead2e |
- if (!stat(module_path, &stat_buf) &&
|
|
|
cead2e |
- (stat_buf.st_mode & S_IFDIR))
|
|
|
cead2e |
- return true;
|
|
|
cead2e |
|
|
|
cead2e |
+#ifdef _LIBXTABLES_DYNAMIC_
|
|
|
cead2e |
+ if (!libxtables_handle && !xtables_load()) {
|
|
|
cead2e |
log_message(LOG_INFO, "Module %s cannot be loaded; not using %s", module, function);
|
|
|
cead2e |
return false;
|
|
|
cead2e |
}
|
|
|
cead2e |
@@ -882,47 +873,50 @@ int ip6tables_add_rules(struct ip6tc_handle* handle, const char* chain_name, uns
|
|
|
cead2e |
#ifdef _LIBIPTC_DYNAMIC_
|
|
|
cead2e |
bool iptables_lib_init(void)
|
|
|
cead2e |
{
|
|
|
cead2e |
- if (libip4tc_handle)
|
|
|
cead2e |
- return true;
|
|
|
cead2e |
-
|
|
|
cead2e |
- /* Attempt to open the ip4tc library */
|
|
|
cead2e |
- if (!(libip4tc_handle = dlopen("libip4tc.so", RTLD_NOW)) &&
|
|
|
cead2e |
- !(libip4tc_handle = dlopen(IP4TC_LIB_NAME, RTLD_NOW))) {
|
|
|
cead2e |
- log_message(LOG_INFO, "Unable to load ip4tc library - %s", dlerror());
|
|
|
cead2e |
- return false;
|
|
|
cead2e |
- }
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (!(iptc_init_addr = dlsym(libip4tc_handle, "iptc_init")) ||
|
|
|
cead2e |
- !(iptc_free_addr = dlsym(libip4tc_handle, "iptc_free")) ||
|
|
|
cead2e |
- !(iptc_is_chain_addr = dlsym(libip4tc_handle,"iptc_is_chain")) ||
|
|
|
cead2e |
- !(iptc_insert_entry_addr = dlsym(libip4tc_handle,"iptc_insert_entry")) ||
|
|
|
cead2e |
- !(iptc_append_entry_addr = dlsym(libip4tc_handle,"iptc_append_entry")) ||
|
|
|
cead2e |
- !(iptc_delete_entry_addr = dlsym(libip4tc_handle,"iptc_delete_entry")) ||
|
|
|
cead2e |
- !(iptc_commit_addr = dlsym(libip4tc_handle,"iptc_commit")) ||
|
|
|
cead2e |
- !(iptc_strerror_addr = dlsym(libip4tc_handle,"iptc_strerror")))
|
|
|
cead2e |
- log_message(LOG_INFO, "Failed to dynamic link an iptc function");
|
|
|
cead2e |
-
|
|
|
cead2e |
- /* Attempt to open the ip6tc library */
|
|
|
cead2e |
- if (!(libip6tc_handle = dlopen("libip6tc.so", RTLD_NOW)) &&
|
|
|
cead2e |
- !(libip6tc_handle = dlopen(IP6TC_LIB_NAME, RTLD_NOW))) {
|
|
|
cead2e |
- log_message(LOG_INFO, "Unable to load ip6tc library - %s", dlerror());
|
|
|
cead2e |
-
|
|
|
cead2e |
- if (global_data->block_ipv4)
|
|
|
cead2e |
+ if (!libip4tc_handle && block_ipv4) {
|
|
|
cead2e |
+ /* Attempt to open the ip4tc library */
|
|
|
cead2e |
+ if (!(libip4tc_handle = dlopen("libip4tc.so", RTLD_NOW)) &&
|
|
|
cead2e |
+ !(libip4tc_handle = dlopen(IP4TC_LIB_NAME, RTLD_NOW))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Unable to load ip4tc library - %s", dlerror());
|
|
|
cead2e |
+ using_libip4tc = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ else if (!(iptc_init_addr = dlsym(libip4tc_handle, "iptc_init")) ||
|
|
|
cead2e |
+ !(iptc_free_addr = dlsym(libip4tc_handle, "iptc_free")) ||
|
|
|
cead2e |
+ !(iptc_is_chain_addr = dlsym(libip4tc_handle,"iptc_is_chain")) ||
|
|
|
cead2e |
+ !(iptc_insert_entry_addr = dlsym(libip4tc_handle,"iptc_insert_entry")) ||
|
|
|
cead2e |
+ !(iptc_append_entry_addr = dlsym(libip4tc_handle,"iptc_append_entry")) ||
|
|
|
cead2e |
+ !(iptc_delete_entry_addr = dlsym(libip4tc_handle,"iptc_delete_entry")) ||
|
|
|
cead2e |
+ !(iptc_commit_addr = dlsym(libip4tc_handle,"iptc_commit")) ||
|
|
|
cead2e |
+ !(iptc_strerror_addr = dlsym(libip4tc_handle,"iptc_strerror"))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Failed to dynamic link an iptc function - %s", dlerror());
|
|
|
cead2e |
+ using_libip4tc = false;
|
|
|
cead2e |
dlclose(libip4tc_handle);
|
|
|
cead2e |
-
|
|
|
cead2e |
- return false;
|
|
|
cead2e |
+ libip4tc_handle = NULL;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
}
|
|
|
cead2e |
|
|
|
cead2e |
- if (!(ip6tc_init_addr = dlsym(libip6tc_handle, "ip6tc_init")) ||
|
|
|
cead2e |
- !(ip6tc_free_addr = dlsym(libip6tc_handle, "ip6tc_free")) ||
|
|
|
cead2e |
- !(ip6tc_is_chain_addr = dlsym(libip6tc_handle,"ip6tc_is_chain")) ||
|
|
|
cead2e |
- !(ip6tc_insert_entry_addr = dlsym(libip6tc_handle,"ip6tc_insert_entry")) ||
|
|
|
cead2e |
- !(ip6tc_append_entry_addr = dlsym(libip6tc_handle,"ip6tc_append_entry")) ||
|
|
|
cead2e |
- !(ip6tc_delete_entry_addr = dlsym(libip6tc_handle,"ip6tc_delete_entry")) ||
|
|
|
cead2e |
- !(ip6tc_commit_addr = dlsym(libip6tc_handle,"ip6tc_commit")) ||
|
|
|
cead2e |
- !(ip6tc_strerror_addr = dlsym(libip6tc_handle,"ip6tc_strerror")))
|
|
|
cead2e |
- log_message(LOG_INFO, "Failed to dynamic link an ip6tc function");
|
|
|
cead2e |
+ if (!libip6tc_handle && block_ipv6) {
|
|
|
cead2e |
+ /* Attempt to open the ip6tc library */
|
|
|
cead2e |
+ if (!(libip6tc_handle = dlopen("libip6tc.so", RTLD_NOW)) &&
|
|
|
cead2e |
+ !(libip6tc_handle = dlopen(IP6TC_LIB_NAME, RTLD_NOW))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Unable to load ip6tc library - %s", dlerror());
|
|
|
cead2e |
+ using_libip6tc = false;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ else if (!(ip6tc_init_addr = dlsym(libip6tc_handle, "ip6tc_init")) ||
|
|
|
cead2e |
+ !(ip6tc_free_addr = dlsym(libip6tc_handle, "ip6tc_free")) ||
|
|
|
cead2e |
+ !(ip6tc_is_chain_addr = dlsym(libip6tc_handle,"ip6tc_is_chain")) ||
|
|
|
cead2e |
+ !(ip6tc_insert_entry_addr = dlsym(libip6tc_handle,"ip6tc_insert_entry")) ||
|
|
|
cead2e |
+ !(ip6tc_append_entry_addr = dlsym(libip6tc_handle,"ip6tc_append_entry")) ||
|
|
|
cead2e |
+ !(ip6tc_delete_entry_addr = dlsym(libip6tc_handle,"ip6tc_delete_entry")) ||
|
|
|
cead2e |
+ !(ip6tc_commit_addr = dlsym(libip6tc_handle,"ip6tc_commit")) ||
|
|
|
cead2e |
+ !(ip6tc_strerror_addr = dlsym(libip6tc_handle,"ip6tc_strerror"))) {
|
|
|
cead2e |
+ log_message(LOG_INFO, "Failed to dynamic link an ip6tc function - %s", dlerror());
|
|
|
cead2e |
+ using_libip6tc = false;
|
|
|
cead2e |
+ dlclose(libip6tc_handle);
|
|
|
cead2e |
+ libip6tc_handle = NULL;
|
|
|
cead2e |
+ }
|
|
|
cead2e |
+ }
|
|
|
cead2e |
|
|
|
cead2e |
- return true;
|
|
|
cead2e |
+ return libip4tc_handle || libip6tc_handle;
|
|
|
cead2e |
}
|
|
|
cead2e |
#endif
|
|
|
cead2e |
--
|
|
|
cead2e |
2.13.5
|
|
|
cead2e |
|