#include <vnet/adj/adj.h>
#include <vnet/adj/adj_mcast.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_sas.h>
#include <vnet/ip/igmp_packet.h>
#include <vnet/ip/ip6_link.h>
#include <vnet/ethernet/arp_packet.h>
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));
- ip4_src_address_for_packet (&ip4_main.lookup_main,
- vr->config.sw_if_index, &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);
+ if (!src4)
+ {
+ return -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);
bi0 = vec_elt (bi, i);
b = vlib_get_buffer (vm, bi0);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index;
else
vrrp_adv_l2_build_multicast (vr, b);
- vrrp_adv_l3_build (vr, b, dst);
+ if (-1 == vrrp_adv_l3_build (vr, b, dst))
+ {
+ vlib_frame_free (vm, to_frame);
+ vlib_buffer_free (vm, bi, n_buffers);
+ return -1;
+ }
vrrp_adv_payload_build (vr, b, shutdown);
vlib_buffer_reset (b);
vlib_put_frame_to_node (vm, node_index, to_frame);
+ vrrp_incr_stat_counter (VRRP_STAT_COUNTER_ADV_SENT, vr->stat_index);
+ if (shutdown)
+ {
+ vrrp_incr_stat_counter (VRRP_STAT_COUNTER_PRIO0_SENT, vr->stat_index);
+ }
+
vec_free (bi);
return 0;
addr = vec_elt_at_index (vr->config.vr_addrs, i);
b = vlib_get_buffer (vm, bi[i]);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index;
vlib_put_frame_to_node (vm, vmp->intf_output_node_idx, to_frame);
+ vec_free (bi);
+
return 0;
}
.dst_address = {.as_u8 = IGMP4_MCAST_ADDR_AS_U8,},
};
-static void
-vrrp_igmp_pkt_build (vrrp_vr_t * vr, vlib_buffer_t * b)
+static int
+vrrp_igmp_pkt_build (vrrp_vr_t *vr, vlib_buffer_t *b)
{
ip4_header_t *ip4;
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));
- ip4_src_address_for_packet (&ip4_main.lookup_main, vr->config.sw_if_index,
- &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);
+ if (!src4)
+ {
+ return -1;
+ }
+ ip4->src_address.as_u32 = src4->as_u32;
vlib_buffer_chain_increase_length (b, b, sizeof (*ip4));
vlib_buffer_advance (b, sizeof (*ip4));
~ip_csum_fold (ip_incremental_checksum (0, report, payload_len));
vlib_buffer_reset (b);
+ return 0;
}
/* multicast listener report packet format for ethernet. */
if (!vnet_sw_interface_is_up (vnm, vr->config.sw_if_index))
return 0;
+ is_ipv6 = vrrp_vr_is_ipv6 (vr);
+
+ if (is_ipv6 && ip6_link_is_enabled (vr->config.sw_if_index) == 0)
+ return 0;
+
if (vlib_buffer_alloc (vm, &bi, n_buffers) != n_buffers)
{
clib_warning ("Buffer allocation failed for %U", format_vrrp_vr_key,
return -1;
}
- is_ipv6 = vrrp_vr_is_ipv6 (vr);
-
b = vlib_get_buffer (vm, bi);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
}
else
{
- vrrp_igmp_pkt_build (vr, b);
+ if (-1 == vrrp_igmp_pkt_build (vr, b))
+ {
+ clib_warning ("IGMP packet build failed for %U", format_vrrp_vr_key,
+ vr);
+ vlib_buffer_free (vm, &bi, 1);
+ return -1;
+ }
node_index = ip4_rewrite_mcast_node.index;
}