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;
127 return memcmp (local_addr, peer_addr, addr_size);
136 if (pkt->priority == 0)
138 clib_warning (
"Received shutdown message from a peer on VR %U",
173 if (pkt->priority == 0)
186 vrt->
master_adv_int = clib_net_to_host_u16 (pkt->rsvd_and_max_adv_int);
214 case VRRP_VR_STATE_INIT:
216 case VRRP_VR_STATE_BACKUP:
220 case VRRP_VR_STATE_MASTER:
222 clib_warning (
"Received advertisement for master VR %U",
227 clib_warning (
"Received advertisement for VR %U in unknown state %d",
251 s =
format (s,
"address %U",
253 (t->
is_ipv6) ? (
void *) &t->
ip.ip6 : (
void *) &t->
ip.ip4);
282 void *lookup_addr = 0;
286 u8 *rewrite, rewrite_len;
290 icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv = 0;
291 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *lladdr = 0;
301 if (ip6->
protocol != IP_PROTOCOL_ICMP6)
305 lladdr = (
void *) (sol_adv + 1);
308 if (sol_adv->icmp.type != ICMP6_neighbor_solicitation)
311 lookup_addr = &sol_adv->target_address;
319 if (arp->
opcode != clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request))
352 rewrite_len =
vec_len (rewrite);
353 if (rewrite_len == 0)
373 IP6_MULTICAST_SCOPE_link_local,
374 IP6_MULTICAST_GROUP_ID_all_hosts);
380 sol_adv->icmp.type = ICMP6_neighbor_advertisement;
381 sol_adv->icmp.checksum = 0;
382 sol_adv->advertisement_flags =
389 lladdr->header.type =
390 ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
392 sol_adv->icmp.checksum =
400 arp->
opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
412 u32 n_left_from, *from, next_index, *to_next;
418 while (n_left_from > 0)
424 while (n_left_from > 0 && n_left_to_next > 0)
444 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
453 icmp6_neighbor_solicitation_or_advertisement_header_t
458 t->
ip.ip6 = sol_adv0->target_address;
477 n_left_to_next, bi0, next0);
496 .name =
"vrrp4-arp-input",
497 .vector_size =
sizeof (
u32),
515 .node_name =
"vrrp4-arp-input",
529 .name =
"vrrp6-nd-input",
530 .vector_size =
sizeof (
u32),
547 .arc_name =
"ip6-local",
548 .node_name =
"vrrp6-nd-input",
556 u32 n_left_from, *from;
562 while (n_left_from > 0)
568 vrrp_header_t *vrrp0;
585 vrrp0 = (vrrp_header_t *) (ip6 + 1);
595 vrrp0 = (vrrp_header_t *) (ip4 + 1);
598 payload_len0 = clib_net_to_host_u16 (ip4->
length) -
sizeof(*ip4);
604 error0 = VRRP_ERROR_RECEIVED;
609 rx_csum0 = vrrp0->checksum;
615 error0 = VRRP_ERROR_BAD_TTL;
620 if ((vrrp0->vrrp_version_and_type >> 4) != 3)
622 error0 = VRRP_ERROR_NOT_VERSION_3;
628 ((
u32) vrrp0->n_addrs) * addr_len)
630 error0 = VRRP_ERROR_INCOMPLETE_PKT;
635 if (rx_csum0 !=
vrrp_adv_csum (ip0, vrrp0, is_ipv6, payload_len0))
637 error0 = VRRP_ERROR_BAD_CHECKSUM;
644 vrrp0->vr_id, is_ipv6)))
646 error0 = VRRP_ERROR_UNKNOWN_VR;
654 error0 = VRRP_ERROR_ADDR_MISMATCH;
666 vrrp0->checksum = rx_csum0;
669 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
672 size_t addr_len = (is_ipv6 ? 16 : 4);
678 (
size_t) vrrp0->n_addrs * addr_len);
700 .name =
"vrrp4-input",
701 .vector_size =
sizeof (
u32),
723 .name =
"vrrp6-input",
724 .vector_size =
sizeof (
u32),
760 s =
format (s,
"IPv%d sw_if_index %d %U -> %U",
768 #define foreach_vrrp_accept_owner_error \ 769 _(RECEIVED, "VRRP owner accept packets received") \ 770 _(PROCESSED, "VRRP owner accept advertisements processed") 774 #define _(sym,str) VRRP_ACCEPT_OWNER_ERROR_##sym, 781 #define _(sym,string) string, 794 u32 *next_index,
u32 *error)
798 if (vr && (vr->
runtime.
state == VRRP_VR_STATE_MASTER) &&
802 *error = VRRP_ACCEPT_OWNER_ERROR_PROCESSED;
810 u32 n_left_from, *from, *to_next;
816 while (n_left_from > 0)
822 while (n_left_from >= 2 && n_left_to_next >= 2)
828 vrrp_header_t *vrrp0, *vrrp1;
831 u32 sw_if_index0, sw_if_index1;
846 error0 = error1 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
859 vrrp0 = (vrrp_header_t *) (ip60 + 1);
861 is_ipv6, &next0, &error0);
865 vrrp1 = (vrrp_header_t *) (ip61 + 1);
867 is_ipv6, &next1, &error1);
877 vrrp0 = (vrrp_header_t *) (ip40 + 1);
879 is_ipv6, &next0, &error0);
883 vrrp1 = (vrrp_header_t *) (ip41 + 1);
885 is_ipv6, &next1, &error1);
892 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
911 if (b1->
flags & VLIB_BUFFER_IS_TRACED)
936 to_next, n_left_to_next,
937 bi0, bi1, next0, next1);
940 while (n_left_from > 0 && n_left_to_next > 0)
946 vrrp_header_t *vrrp0;
959 error0 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
970 vrrp0 = (vrrp_header_t *) (ip6 + 1);
972 is_ipv6, &next0, &error0);
981 vrrp0 = (vrrp_header_t *) (ip4 + 1);
983 is_ipv6, &next0, &error0);
989 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
1011 n_left_to_next -= 1;
1014 to_next, n_left_to_next,
1033 .name =
"vrrp4-accept-owner-input",
1034 .vector_size =
sizeof (
u32),
1050 .arc_name =
"ip4-multicast",
1051 .node_name =
"vrrp4-accept-owner-input",
1064 .name =
"vrrp6-accept-owner-input",
1065 .vector_size =
sizeof (
u32),
1081 .arc_name =
"ip6-multicast",
1082 .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)
ip_lookup_main_t lookup_main
#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
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[]
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)
ip4_main_t ip4_main
Global ip4 main structure.
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 int ip4_src_address_for_packet(ip_lookup_main_t *lm, u32 sw_if_index, ip4_address_t *src)
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)