aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Smith <mgsmith@netgate.com>2021-08-25 17:09:34 -0500
committerDamjan Marion <dmarion@me.com>2021-09-08 14:40:23 +0000
commit0d56f60c8c9c3c86b6b47f369d23b8c79366aedf (patch)
tree7ec1fdc92e0b8f52ee48cbb8421ab37e1540b5b8
parentf49734d3b9afb27e3f527e1477fee4952d546f9a (diff)
vrrp: fix source address on advertisements
Type: fix Advertisements are dropped by anti spoofing check in some situations. When a VR has "accept mode" enabled, we must add the virtual IP addresses to the interface when the VR transitions to master state. When this happens, fib_sas4_get() starts selecting the newly added virtual IP address as the source address for packets sent on the interface, so advertisements are sent with that source address. When the virtual IP address is being used as a NAT pool address on a peer in the backup state, the peer sees the address as a local address and drops incoming advertisements with that source address. RFC 5798 section 5.1.1.1 says advertisements should use the primary IPv4 address of the interface they are being sent on as the source IP address. Since the virtual IP address is only temporarily added while the VR is in the master state, the virtual IP address should probably not be considered the primary address of the interface. The definition of Primary IP Address in section 1.6 says that selecting the first address is a valid selection algorithm. Do that instead of calling fib_sas4_get(). Change-Id: Id92f0e3237c7fd491dd8d695bb27307d494f8573 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
-rw-r--r--src/plugins/vrrp/vrrp_packet.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/plugins/vrrp/vrrp_packet.c b/src/plugins/vrrp/vrrp_packet.c
index b470ddeba08..84bd3701edb 100644
--- a/src/plugins/vrrp/vrrp_packet.c
+++ b/src/plugins/vrrp/vrrp_packet.c
@@ -102,13 +102,20 @@ vrrp_adv_l3_build (vrrp_vr_t * vr, vlib_buffer_t * b,
if (!vrrp_vr_is_ipv6 (vr)) /* IPv4 */
{
ip4_header_t *ip4 = vlib_buffer_get_current (b);
+ ip4_address_t *src4;
clib_memset (ip4, 0, sizeof (*ip4));
ip4->ip_version_and_header_length = 0x45;
ip4->ttl = 255;
ip4->protocol = IP_PROTOCOL_VRRP;
clib_memcpy (&ip4->dst_address, &dst->ip4, sizeof (dst->ip4));
- fib_sas4_get (vr->config.sw_if_index, NULL, &ip4->src_address);
+
+ /* RFC 5798 Section 5.1.1.1 - Source Address "is the primary IPv4
+ * address of the interface the packet is being sent from". Assume
+ * this is the first address on the interface.
+ */
+ src4 = ip_interface_get_first_ip (vr->config.sw_if_index, 1);
+ ip4->src_address.as_u32 = src4->as_u32;
ip4->length = clib_host_to_net_u16 (sizeof (*ip4) +
vrrp_adv_payload_len (vr));
ip4->checksum = ip4_header_checksum (ip4);
@@ -536,10 +543,14 @@ vrrp_igmp_pkt_build (vrrp_vr_t * vr, vlib_buffer_t * b)
u8 *ip4_options;
igmp_membership_report_v3_t *report;
igmp_membership_group_v3_t *group;
+ ip4_address_t *src4;
ip4 = vlib_buffer_get_current (b);
clib_memcpy (ip4, &igmp_ip4_mcast, sizeof (*ip4));
- fib_sas4_get (vr->config.sw_if_index, NULL, &ip4->src_address);
+
+ /* Use the source address advertisements will use to join mcast group */
+ src4 = ip_interface_get_first_ip (vr->config.sw_if_index, 1);
+ ip4->src_address.as_u32 = src4->as_u32;
vlib_buffer_chain_increase_length (b, b, sizeof (*ip4));
vlib_buffer_advance (b, sizeof (*ip4));