Skip to content

Commit

Permalink
vrrp: Set sysctl arp_ignore to 1 on IPv6 VMACs
Browse files Browse the repository at this point in the history
Setting arp_ignore to 1 ensures that the VMAC interface does not respond
to ARP requests for IPv4 addresses not configured on the VMAC.

Signed-off-by: Quentin Armitage <[email protected]>
  • Loading branch information
pqarmitage committed Oct 14, 2023
1 parent 5a54d67 commit 9ca8688
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
2 changes: 1 addition & 1 deletion keepalived/include/vrrp_if_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extern void set_promote_secondaries(interface_t*);
extern void reset_promote_secondaries(interface_t*);
#ifdef _HAVE_VRRP_VMAC_
extern void restore_rp_filter(void);
extern void set_interface_parameters(const interface_t*, interface_t*);
extern void set_interface_parameters(const interface_t*, interface_t*, sa_family_t);
extern void reset_interface_parameters(interface_t*);
extern void link_set_ipv6(const interface_t*, bool);
#endif
Expand Down
28 changes: 20 additions & 8 deletions keepalived/vrrp/vrrp_if_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ static sysctl_opts_t vmac_sysctl[] = {
{ 0, 0}
};

static sysctl_opts_t vmac_sysctl_6[] = {
{ IPV4_DEVCONF_ARP_IGNORE, 1 },
{ 0, 0}
};

#endif
#endif

Expand Down Expand Up @@ -216,11 +221,14 @@ netlink_set_interface_flags(unsigned ifindex, const sysctl_opts_t *sys_opts)

#ifdef _HAVE_VRRP_VMAC_
static inline int
netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
{
if (netlink_set_interface_flags(ifp->ifindex, vmac_sysctl))
if (netlink_set_interface_flags(ifp->ifindex, family == AF_INET6 ? vmac_sysctl_6 : vmac_sysctl))
return -1;

if (family == AF_INET6)
return 0;

/* If the underlying interface is a MACVLAN that has been moved into
* a separate network namespace from the parent, we can't access the
* parent. */
Expand Down Expand Up @@ -271,9 +279,9 @@ netlink_reset_interface_parameters(const interface_t* ifp)
}

static inline void
set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp)
set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
{
if (netlink_set_interface_parameters(ifp, base_ifp))
if (netlink_set_interface_parameters(ifp, base_ifp, family))
log_message(LOG_INFO, "Unable to set parameters for %s", ifp->ifname);
}

Expand Down Expand Up @@ -310,11 +318,15 @@ reset_promote_secondaries_devconf(interface_t *ifp)

#ifdef _HAVE_VRRP_VMAC_
static inline void
set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp)
set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
{
unsigned val;

set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 1);

if (family == AF_INET6)
return;

set_sysctl("net/ipv4/conf", ifp->ifname, "accept_local", 1);
set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0);

Expand Down Expand Up @@ -524,15 +536,15 @@ restore_rp_filter(void)
}

void
set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
{
if (all_rp_filter == UINT_MAX)
clear_rp_filter();

#ifdef _HAVE_IPV4_DEVCONF_
set_interface_parameters_devconf(ifp, base_ifp);
set_interface_parameters_devconf(ifp, base_ifp, family);
#else
set_interface_parameters_sysctl(ifp, base_ifp);
set_interface_parameters_sysctl(ifp, base_ifp, family);
#endif
}

Expand Down
5 changes: 2 additions & 3 deletions keepalived/vrrp/vrrp_vmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,9 @@ netlink_link_add_vmac(vrrp_t *vrrp, const interface_t *old_interface)
if (!ifp->ifindex)
return false;

if (vrrp->family == AF_INET && create_interface) {
if (create_interface) {
/* Set the necessary kernel parameters to make macvlans work for us */
// If this saves current base_ifp's settings, we need to be careful if multiple VMACs on same i/f
set_interface_parameters(ifp, ifp->base_ifp);
set_interface_parameters(ifp, ifp->base_ifp, vrrp->family);
}

#ifdef _WITH_FIREWALL_
Expand Down

0 comments on commit 9ca8688

Please sign in to comment.