aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Smith <mgsmith@netgate.com>2020-09-16 16:41:26 -0500
committerMatthew Smith <mgsmith@netgate.com>2020-09-21 15:12:49 +0000
commit4b1b13315a3c532d45fb41cc3ce34a48ad72a757 (patch)
treeb77567b28daacfa31c789ac4ee44b7e0e3ca99d0
parent8157a161c613c3cc83c1c4507ed141b21b9627b5 (diff)
vrrp: set up multicast for both address families
Type: fix When a VR is added, multicast accept routes are added which allow inbound packets sent to the VRRP group address on the interface of the VR so advertisements from peers can be received. If this is the first VR added, also add a local forward route for the VRRP group address so the packets will be processed by the VRRP input nodes. When deciding whether to add/delete the local forward route, the total number of VRs configured was being checked. If there are no VRs configured initially and a VR is added for IPv4, this check would correctly see that this was the first VR and add an IPv4 route. If an IPv6 VR was configured subsequently, this check would find that a VR was already configured and incorrectly decide that no route needed to be added and IPv6 VRRP advertisements from peers would be dropped as a result. The opposite would occur if you first added an IPv6 VR followed by adding an IPv4 VR - whichever address family was added first would work correctly and the other one would not work. Since a route is needed for each address family, check on the per address family count of VRs when deciding whether to add/delete the local forward route instead of checking on the global count of VRs. Change-Id: I851a7ef8a4f9e4e370d08b0832284a13387eb083 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
-rw-r--r--src/plugins/vrrp/vrrp.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/plugins/vrrp/vrrp.c b/src/plugins/vrrp/vrrp.c
index eb988d323c9..37ee9ec25a6 100644
--- a/src/plugins/vrrp/vrrp.c
+++ b/src/plugins/vrrp/vrrp.c
@@ -382,8 +382,10 @@ static int
vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
{
vrrp_main_t *vrm = &vrrp_main;
+ vrrp_vr_t *vr;
vrrp_intf_t *intf;
u32 fib_index;
+ u32 n_vrs = 0;
const mfib_prefix_t *vrrp_prefix;
fib_protocol_t proto;
vnet_link_t link_type;
@@ -418,9 +420,18 @@ vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
via_itf.frp_proto = fib_proto_to_dpo (proto);
fib_index = mfib_table_get_index_for_sw_if_index (proto, sw_if_index);
+ /* *INDENT-OFF* */
+ pool_foreach (vr, vrm->vrs,
+ ({
+ if (vrrp_vr_is_ipv6 (vr) == is_ipv6)
+ n_vrs++;
+ }));
+ /* *INDENT-ON* */
+
if (enable)
{
- if (pool_elts (vrm->vrs) == 1)
+ /* If this is the first VR configured, add the local mcast routes */
+ if (n_vrs == 1)
mfib_table_entry_path_update (fib_index, vrrp_prefix, MFIB_SOURCE_API,
&for_us);
@@ -431,7 +442,8 @@ vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
}
else
{
- if (pool_elts (vrm->vrs) == 0)
+ /* Remove mcast local routes if this is the last VR being deleted */
+ if (n_vrs == 0)
mfib_table_entry_path_remove (fib_index, vrrp_prefix, MFIB_SOURCE_API,
&for_us);