37 s =
format (s,
"VRRP: sw_if_index %d IPv%d\n",
40 s =
format (s,
" addresses: ");
42 for (i = 0; i < t->
vrrp.n_addrs; i++)
46 (ip6_address_t *) (t->
addrs + i * 16));
60 #define foreach_vrrp_error \ 61 _(RECEIVED, "VRRP packets processed") \ 62 _(BAD_TTL, "VRRP advertisement TTL is not 255") \ 63 _(NOT_VERSION_3, "VRRP version is not 3") \ 64 _(INCOMPLETE_PKT, "VRRP packet has wrong size") \ 65 _(BAD_CHECKSUM, "VRRP checksum is invalid") \ 66 _(UNKNOWN_VR, "VRRP message does not match known VRs") \ 67 _(ADDR_MISMATCH, "VR addrs do not match configuration") 71 #define _(sym,str) VRRP_ERROR_##sym, 78 #define _(sym,string) string, 104 void *peer_addr, *local_addr;
113 local_addr = &addr.ip6;
121 local_addr = &addr.ip4;
126 return memcmp (local_addr, peer_addr, addr_size);
135 if (pkt->priority == 0)
137 clib_warning (
"Received shutdown message from a peer on VR %U",
172 if (pkt->priority == 0)
185 vrt->
master_adv_int = clib_net_to_host_u16 (pkt->rsvd_and_max_adv_int);
213 case VRRP_VR_STATE_INIT:
215 case VRRP_VR_STATE_BACKUP:
219 case VRRP_VR_STATE_MASTER:
221 clib_warning (
"Received advertisement for master VR %U",
226 clib_warning (
"Received advertisement for VR %U in unknown state %d",
250 s =
format (s,
"address %U",
252 (t->
is_ipv6) ? (
void *) &t->
ip.ip6 : (
void *) &t->
ip.ip4);
281 void *lookup_addr = 0;
285 u8 *rewrite, rewrite_len;
289 icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv = 0;
290 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *lladdr = 0;
300 if (ip6->
protocol != IP_PROTOCOL_ICMP6)
304 lladdr = (
void *) (sol_adv + 1);
307 if (sol_adv->icmp.type != ICMP6_neighbor_solicitation)
310 lookup_addr = &sol_adv->target_address;
318 if (arp->
opcode != clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request))
351 rewrite_len =
vec_len (rewrite);
352 if (rewrite_len == 0)
372 IP6_MULTICAST_SCOPE_link_local,
373 IP6_MULTICAST_GROUP_ID_all_hosts);
379 sol_adv->icmp.type = ICMP6_neighbor_advertisement;
380 sol_adv->icmp.checksum = 0;
381 sol_adv->advertisement_flags =
388 lladdr->header.type =
389 ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
391 sol_adv->icmp.checksum =
399 arp->
opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
411 u32 n_left_from, *from, next_index, *to_next;
417 while (n_left_from > 0)
423 while (n_left_from > 0 && n_left_to_next > 0)
443 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
452 icmp6_neighbor_solicitation_or_advertisement_header_t
457 t->
ip.ip6 = sol_adv0->target_address;
476 n_left_to_next, bi0, next0);
495 .name =
"vrrp4-arp-input",
496 .vector_size =
sizeof (
u32),
514 .node_name =
"vrrp4-arp-input",
528 .name =
"vrrp6-nd-input",
529 .vector_size =
sizeof (
u32),
546 .arc_name =
"ip6-local",
547 .node_name =
"vrrp6-nd-input",
555 u32 n_left_from, *from;
561 while (n_left_from > 0)
567 vrrp_header_t *vrrp0;
584 vrrp0 = (vrrp_header_t *) (ip6 + 1);
594 vrrp0 = (vrrp_header_t *) (ip4 + 1);
597 payload_len0 = clib_net_to_host_u16 (ip4->
length) -
sizeof(*ip4);
603 error0 = VRRP_ERROR_RECEIVED;
608 rx_csum0 = vrrp0->checksum;
614 error0 = VRRP_ERROR_BAD_TTL;
619 if ((vrrp0->vrrp_version_and_type >> 4) != 3)
621 error0 = VRRP_ERROR_NOT_VERSION_3;
627 ((
u32) vrrp0->n_addrs) * addr_len)
629 error0 = VRRP_ERROR_INCOMPLETE_PKT;
634 if (rx_csum0 !=
vrrp_adv_csum (ip0, vrrp0, is_ipv6, payload_len0))
636 error0 = VRRP_ERROR_BAD_CHECKSUM;
643 vrrp0->vr_id, is_ipv6)))
645 error0 = VRRP_ERROR_UNKNOWN_VR;
653 error0 = VRRP_ERROR_ADDR_MISMATCH;
665 vrrp0->checksum = rx_csum0;
668 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
671 size_t addr_len = (is_ipv6 ? 16 : 4);
677 (
size_t) vrrp0->n_addrs * addr_len);
699 .name =
"vrrp4-input",
700 .vector_size =
sizeof (
u32),
722 .name =
"vrrp6-input",
723 .vector_size =
sizeof (
u32),
759 s =
format (s,
"IPv%d sw_if_index %d %U -> %U",
767 #define foreach_vrrp_accept_owner_error \ 768 _(RECEIVED, "VRRP owner accept packets received") \ 769 _(PROCESSED, "VRRP owner accept advertisements processed") 773 #define _(sym,str) VRRP_ACCEPT_OWNER_ERROR_##sym, 780 #define _(sym,string) string, 797 if (vr && (vr->
runtime.
state == VRRP_VR_STATE_MASTER) &&
801 *error = VRRP_ACCEPT_OWNER_ERROR_PROCESSED;
809 u32 n_left_from, *from, *to_next;
815 while (n_left_from > 0)
821 while (n_left_from >= 2 && n_left_to_next >= 2)
827 vrrp_header_t *vrrp0, *vrrp1;
830 u32 sw_if_index0, sw_if_index1;
845 error0 = error1 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
858 vrrp0 = (vrrp_header_t *) (ip60 + 1);
860 is_ipv6, &next0, &error0);
864 vrrp1 = (vrrp_header_t *) (ip61 + 1);
866 is_ipv6, &next1, &error1);
876 vrrp0 = (vrrp_header_t *) (ip40 + 1);
878 is_ipv6, &next0, &error0);
882 vrrp1 = (vrrp_header_t *) (ip41 + 1);
884 is_ipv6, &next1, &error1);
891 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
910 if (b1->
flags & VLIB_BUFFER_IS_TRACED)
935 to_next, n_left_to_next,
936 bi0, bi1, next0, next1);
939 while (n_left_from > 0 && n_left_to_next > 0)
945 vrrp_header_t *vrrp0;
958 error0 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
969 vrrp0 = (vrrp_header_t *) (ip6 + 1);
971 is_ipv6, &next0, &error0);
980 vrrp0 = (vrrp_header_t *) (ip4 + 1);
982 is_ipv6, &next0, &error0);
988 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
1010 n_left_to_next -= 1;
1013 to_next, n_left_to_next,
1032 .name =
"vrrp4-accept-owner-input",
1033 .vector_size =
sizeof (
u32),
1049 .arc_name =
"ip4-multicast",
1050 .node_name =
"vrrp4-accept-owner-input",
1063 .name =
"vrrp6-accept-owner-input",
1064 .vector_size =
sizeof (
u32),
1080 .arc_name =
"ip6-multicast",
1081 .node_name =
"vrrp6-accept-owner-input",
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static void vrrp_input_process_master(vrrp_vr_t *vr, vrrp_header_t *pkt)
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
vlib_node_registration_t vrrp6_nd_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_nd_input_node)
vlib_node_registration_t vrrp4_arp_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_arp_input_node)
void ip6_register_protocol(u32 protocol, u32 node_index)
static clib_error_t * vrrp_init(vlib_main_t *vm)
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
vnet_main_t * vnet_get_main(void)
#define clib_memcpy_fast(a, b, c)
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_node_registration_t vrrp6_accept_owner_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_accept_owner_input_node)
u16 current_length
Nbytes between current data and the end of this buffer.
static int vrrp_vr_addr_cmp(vrrp_vr_t *vr, vrrp_header_t *pkt)
#define VLIB_NODE_FN(node)
struct vrrp_input_process_args vrrp_input_process_args_t
void ip4_register_protocol(u32 protocol, u32 node_index)
vlib_error_t * errors
Vector of errors for this node.
static vrrp_vr_t * vrrp_vr_lookup_index(u32 vr_index)
#define clib_memcpy(d, s, n)
static_always_inline uword vrrp_accept_owner_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
#define static_always_inline
vrrp_accept_owner_error_t
#define VLIB_INIT_FUNCTION(x)
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
description fragment has unexpected format
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
static void vrrp_input_process_backup(vrrp_vr_t *vr, vrrp_header_t *pkt)
vlib_node_registration_t vrrp4_accept_owner_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_accept_owner_input_node)
#define vlib_call_init_function(vm, x)
u16 vrrp_adv_csum(void *l3_hdr, void *payload, u8 is_ipv6, u16 len)
u8 * format_vrrp_packet_hdr(u8 *s, va_list *args)
vl_api_fib_path_type_t type
vlib_error_t error
Error code for buffers to be enqueued to error handler.
vlib_node_registration_t vrrp4_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_input_node)
static ethernet_header_t * ethernet_buffer_get_header(vlib_buffer_t *b)
u8 * format_vrrp_vr_key(u8 *s, va_list *args)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vrrp_vr_runtime_t runtime
static_always_inline uword vrrp_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
static void vrrp_vr_master_down_compute(vrrp_vr_t *vr)
vl_api_address_union_t src_address
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
static char * vrrp_error_strings[]
static_always_inline void vrrp_accept_owner_next_node(u32 sw_if_index, u8 vr_id, u8 is_ipv6, u32 *next_index, u32 *error)
static u8 vrrp_vr_is_ipv6(vrrp_vr_t *vr)
format_function_t format_ip46_address
#define VLIB_REGISTER_NODE(x,...)
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
#define clib_warning(format, args...)
vlib_node_registration_t vrrp6_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_input_node)
#define foreach_vrrp_error
#define foreach_vrrp_accept_owner_error
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static u8 vrrp_vr_priority(vrrp_vr_t *vr)
static void * ip6_next_header(ip6_header_t *i)
vlib_main_t vlib_node_runtime_t * node
static void vrrp_input_process(vrrp_input_process_args_t *args)
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static u8 * format_vrrp_accept_owner_trace(u8 *s, va_list *args)
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
int vrrp_adv_send(vrrp_vr_t *vr, int shutdown)
void vrrp_vr_timer_set(vrrp_vr_t *vr, vrrp_vr_timer_type_t type)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define VNET_FEATURES(...)
static vlib_main_t * vlib_get_main(void)
struct _vlib_node_registration vlib_node_registration_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u8 * format_vrrp_trace(u8 *s, va_list *args)
const ip6_address_t * ip6_get_link_local_address(u32 sw_if_index)
static char * vrrp_accept_owner_error_strings[]
bool fib_sas4_get(u32 sw_if_index, const ip4_address_t *dst, ip4_address_t *src)
Get an IPv4 Source address to use in a packet being sent out an interface.
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
static u8 * format_vrrp_arp_nd_input_trace(u8 *s, va_list *va)
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static int vrrp_intf_num_vrs(u32 sw_if_index, u8 is_ipv6)
u8 * ethernet_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
build a rewrite string to use for sending packets of type 'link_type' to 'dst_address' ...
static vrrp_vr_t * vrrp_vr_lookup(u32 sw_if_index, u8 vr_id, u8 is_ipv6)
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
static uword ip6_address_is_unspecified(const ip6_address_t *a)
static clib_error_t * vrrp_input_init(vlib_main_t *vm)
static_always_inline uword vrrp_arp_nd_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
ip46_address_t * vr_addrs
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static_always_inline void vrrp_arp_nd_next(vlib_buffer_t *b, u32 *next_index, u32 *vr_index, u8 is_ipv6)
static void vrrp_vr_skew_compute(vrrp_vr_t *vr)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vl_api_interface_index_t sw_if_index
static void ip6_set_reserved_multicast_address(ip6_address_t *a, ip6_multicast_address_scope_t scope, u16 id)
VNET_FEATURE_INIT(lb_nat4_in2out_node_fn, static)
static u32 vrrp_vr_lookup_address(u32 sw_if_index, u8 is_ipv6, void *addr)
void vrrp_vr_transition(vrrp_vr_t *vr, vrrp_vr_state_t new_state, void *data)