23 #include <vpp/app/version.h> 28 .
bytes = {0x00, 0x00, 0x5e, 0x00, 0x01, 0x00}
32 .
bytes = {0x00, 0x00, 0x5e, 0x00, 0x02, 0x00}
92 return vr_count.
count;
109 u8 enable = (new_state == VRRP_VR_STATE_MASTER);
118 if ((enable && !n_master_vrs) || (!enable && (n_master_vrs < 2)))
120 clib_warning (
"%s virtual MAC address %U on hardware interface %u",
121 (enable) ?
"Adding" :
"Deleting",
142 const char *arc_name = 0, *node_name = 0;
147 (new_state != VRRP_VR_STATE_MASTER))
152 arc_name =
"ip6-local";
153 node_name =
"vrrp6-nd-input";
158 node_name =
"vrrp4-arp-input";
162 if (new_state == VRRP_VR_STATE_MASTER)
186 ip46_address_t *vr_addr;
200 (new_state != VRRP_VR_STATE_MASTER))
203 is_del = (new_state != VRRP_VR_STATE_MASTER);
232 ip6_address_t *intf6;
259 if (new_state == VRRP_VR_STATE_MASTER)
271 else if (new_state == VRRP_VR_STATE_BACKUP)
281 vrrp_header_t *pkt =
data;
293 else if (new_state == VRRP_VR_STATE_INIT)
303 else if (new_state == VRRP_VR_STATE_INTF_DOWN)
322 #define VRRP4_MCAST_ADDR_AS_U8 { 224, 0, 0, 18 } 323 #define VRRP6_MCAST_ADDR_AS_U8 \ 324 { 0xff, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12 } 431 if (per_intf_index != ~0)
450 ip46_address_t *
addr;
456 return VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
465 ip46_address_t *vr_addr;
473 addr = (
is_ipv6) ? (
void *) &vr_addr->ip6 : (
void *) &vr_addr->ip4;
476 return VNET_API_ERROR_ADDRESS_IN_USE;
503 vrrp4_arp_key_t key4;
505 ip46_address_t *
addr;
508 return VNET_API_ERROR_INVALID_ARGUMENT;
510 vr_index = vr - vmp->
vrs;
515 key6.addr = vr_addr->ip6;
537 key4.addr = vr_addr->ip4;
563 ip46_address_t *vr_addr;
585 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
600 clib_warning (
"VR %u for IPv%d already exists on sw_if_index %u",
602 return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
608 clib_warning (
"Conf of VR %u for IPv%d on sw_if_index %u " 609 " does not contain IP addresses",
611 return VNET_API_ERROR_INVALID_SRC_ADDRESS;
619 vr_index = vr - vrm->
vrs;
639 clib_warning (
"No VR %u for IPv%d exists on sw_if_index %u",
641 return VNET_API_ERROR_NO_SUCH_ENTRY;
669 return VNET_API_ERROR_NO_SUCH_ENTRY;
676 case VRRP_VR_STATE_INIT:
679 clib_warning (
"Attempting to stop already stopped VR (%U)",
687 clib_warning (
"Attempting to start already started VR (%U)",
699 return VNET_API_ERROR_INIT_FAILED;
735 return VNET_API_ERROR_INVALID_ARGUMENT;
741 return VNET_API_ERROR_RSRC_IN_USE;
747 return VNET_API_ERROR_INVALID_DST_ADDRESS;
763 return VNET_API_ERROR_NO_SUCH_ENTRY;
866 int admin_up, link_up, ip_up;
872 return (admin_up && link_up && ip_up);
885 u32 total_priority = 0;
897 clib_warning (
"VR %U interface track adjustment change from %u to %u",
914 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
918 return VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
957 ifs_copy =
vec_dup (track_ifs);
970 for (rb_if = track_if - 1; rb_if >= track_ifs; rb_if -= 1)
1025 for (i = 0; i < 2; i++)
1046 vr_state = VRRP_VR_STATE_INTF_DOWN;
1053 VRRP_VR_STATE_MASTER : VRRP_VR_STATE_BACKUP;
1102 .hw_if_index = hw_if_index,
1121 u32 if_address_index,
u32 is_del)
1132 u32 indent = va_arg (*args,
u32);
1138 s =
format (s,
"%UVRRP VRs monitoring this link:\n",
1229 .version = VPP_BUILD_VER,
1230 .description =
"VRRP v3 (RFC 5798)",
static u8 * format_vrrp_ip6_link(u8 *s, va_list *args)
u8 ip_interface_has_address(u32 sw_if_index, ip46_address_t *ip, u8 is_ip4)
static int vrrp_vr_valid_addrs(vrrp_vr_config_t *vr_conf)
u8 * format_vrrp_vr_state(u8 *s, va_list *args)
#define vec_foreach_index(var, v)
Iterate over vector indices.
static u8 vrrp_vr_is_unicast(vrrp_vr_t *vr)
clib_error_t * vrrp_sw_interface_up_down(vrrp_intf_update_t *pending)
#define hash_set(h, key, value)
static void vrrp_vr_transition_addrs(vrrp_vr_t *vr, vrrp_vr_state_t new_state)
static u32 vrrp_vr_index(vrrp_vr_t *vr)
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(vrrp_sw_interface_admin_up_down)
vrrp_vr_tracking_t tracking
#define hash_unset(h, key)
int vrrp_vr_start_stop(u8 is_start, vrrp_vr_key_t *vr_key)
A representation of a path as described by a route producer.
static clib_error_t * vrrp_init(vlib_main_t *vm)
vnet_main_t * vnet_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * ip4_lookup_init(vlib_main_t *vm)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
#define VRRP4_MCAST_ADDR_AS_U8
adj_index_t mcast_adj_index[2]
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(vrrp_hw_interface_link_up_down)
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
static const mfib_prefix_t all_vrrp6_routers
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
void vrrp_vr_transition_vmac(vrrp_vr_t *vr, vrrp_vr_state_t new_state)
void vnet_hw_interface_walk_sw(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_sw_interface_walk_t fn, void *ctx)
Walk the SW interfaces on a HW interface - this is the super interface and any sub-interfaces.
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static int vrrp_intf_sw_admin_up(u32 sw_if_index, vrrp_intf_update_t *pending)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
int vrrp_vr_set_peers(vrrp_vr_key_t *vr_key, ip46_address_t *peers)
dpo_proto_t frp_proto
The protocol of the address below.
void vrrp_vr_tracking_ifs_compute(vrrp_vr_t *vr, vrrp_intf_update_t *pending)
static int vrrp_intf_is_up(u32 sw_if_index, u8 is_ipv6, vrrp_intf_update_t *pending)
static int vrrp_intf_hw_link_up(u32 sw_if_index, vrrp_intf_update_t *pending)
static u16 vrrp_adv_int_from_packet(vrrp_header_t *pkt)
static vrrp_vr_t * vrrp_vr_lookup_index(u32 vr_index)
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define clib_memcpy(d, s, n)
enum walk_rc_t_ walk_rc_t
Walk return code.
static const u8 vrrp_prefix[]
u8 * format_ethernet_address(u8 *s, va_list *args)
u32 frp_sw_if_index
The interface.
vl_api_interface_index_t sw_if_index
#define VLIB_INIT_FUNCTION(x)
u32 mfib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
static void vrrp_intf_ip6_enable_disable(u32 sw_if_index, int enable)
static void vrrp_vr_transition_intf(vrrp_vr_t *vr, vrrp_vr_state_t new_state)
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static int vrrp_intf_vr_add_del(u8 is_add, u32 sw_if_index, u32 vr_index, u8 is_ipv6)
static u8 vrrp_vr_is_owner(vrrp_vr_t *vr)
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
#define vlib_call_init_function(vm, x)
static uword vnet_sw_interface_is_valid(vnet_main_t *vnm, u32 sw_if_index)
static u8 vrrp_vr_accept_mode_enabled(vrrp_vr_t *vr)
clib_error_t * ip4_add_del_interface_address(vlib_main_t *vm, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 is_del)
static void vrrp_intf_tracking_vrs_compute(u32 sw_if_index, vrrp_intf_update_t *pending, u8 is_ipv6)
#define hash_create_mem(elts, key_bytes, value_bytes)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
u8 * format_vrrp_vr_key(u8 *s, va_list *args)
static walk_rc_t vrrp_hwif_master_count_walk(vnet_main_t *vnm, u32 sw_if_index, void *arg)
int vrrp_garp_or_na_send(vrrp_vr_t *vr)
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
#define vec_del1(v, i)
Delete the element at index I.
vrrp_vr_runtime_t runtime
static void vrrp_vr_master_down_compute(vrrp_vr_t *vr)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
ip6_link_delegate_id_t ip6_link_delegate_register(const ip6_link_delegate_vft_t *vft)
static u8 vrrp_vr_is_ipv6(vrrp_vr_t *vr)
int vrrp_vr_multicast_group_join(vrrp_vr_t *vr)
int vrrp_vr_tracking_if_add_del(vrrp_vr_t *vr, u32 sw_if_index, u8 prio, u8 is_add)
static const mfib_prefix_t all_vrrp4_routers
static void vrrp_intf_tracking_vr_add_del(u32 sw_if_index, vrrp_vr_t *vr, u8 is_add)
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
ip4_add_del_interface_address_function_t * function
static void vrrp_vr_addrs_add_del(vrrp_vr_t *vr, u8 is_add, ip46_address_t *vr_addrs)
static ip4_address_t * ip4_interface_address_matching_destination(ip4_main_t *im, const ip4_address_t *dst, u32 sw_if_index, ip_interface_address_t **result_ia)
#define clib_warning(format, args...)
static int vrrp_vr_valid_addrs_owner(vrrp_vr_config_t *vr_conf)
static int vrrp_intf_ip_up(u32 sw_if_index, u8 is_ipv6, vrrp_intf_update_t *pending)
vrrp_intf_update_type_t type
Aggregate type for a prefix.
#define hash_create(elts, value_bytes)
static walk_rc_t vrrp_hw_interface_link_up_down_walk(vnet_main_t *vnm, u32 sw_if_index, void *arg)
u32 ip6_link_delegate_id_t
manual_print typedef address
static uword * mhash_get(mhash_t *h, const void *key)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
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)
vrrp_vr_tracking_if_t * interfaces
void vrrp_vr_timer_set(vrrp_vr_t *vr, vrrp_vr_timer_type_t type)
static int vrrp_vr_valid_addrs_unused(vrrp_vr_config_t *vr_conf)
int vrrp_vr_add_del(u8 is_add, vrrp_vr_config_t *vr_conf)
#define clib_error_report(e)
static void hash_unset_mem_free(uword **h, const void *key)
enum vrrp_vr_state vrrp_vr_state_t
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
static ip6_link_delegate_id_t vrrp_ip6_delegate_id
static vlib_main_t * vlib_get_main(void)
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
#define vec_elt(v, i)
Get vector value at index i.
fib_protocol_t fp_proto
protocol type
static void vrrp_ip4_add_del_interface_addr(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_del)
static vrrp_intf_t * vrrp_intf_get(u32 sw_if_index)
void vrrp_vr_timer_cancel(vrrp_vr_t *vr)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u32 vrrp_vr_hwif_master_vrs_by_vrid(u32 hw_if_index, u8 vr_id, u8 is_ipv6)
static int vrrp_vr_set_peers_validate(vrrp_vr_t *vr, ip46_address_t *peers)
static int vrrp_intf_enable_disable_mcast(u8 enable, u32 sw_if_index, u8 is_ipv6)
clib_error_t * vrrp_plugin_api_hookup(vlib_main_t *vm)
static vrrp_vr_t * vrrp_vr_lookup(u32 sw_if_index, u8 vr_id, u8 is_ipv6)
bool ip6_link_is_enabled(u32 sw_if_index)
static void vrrp_intf_ip6_disable(index_t indi)
static clib_error_t * vrrp_hw_interface_link_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
ip4_main_t ip4_main
Global ip4 main structure.
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
#define vec_foreach(var, vec)
Vector iterator.
ip46_address_t * vr_addrs
clib_error_t * ip6_add_del_interface_address(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *address, u32 address_length, u32 is_del)
static void hash_set_mem_alloc(uword **h, const void *key, uword v)
ip6_link_enable_fn_t ildv_enable
clib_error_t * vnet_hw_interface_add_del_mac_address(vnet_main_t *vnm, u32 hw_if_index, const u8 *mac_address, u8 is_add)
static void vrrp_intf_ip6_enable(u32 sw_if_index)
static ip6_address_t * ip6_interface_address_matching_destination(ip6_main_t *im, const ip6_address_t *dst, u32 sw_if_index, ip_interface_address_t **result_ia)
static clib_error_t * ip6_lookup_init(vlib_main_t *vm)
ip46_address_t * peer_addrs
void mfib_table_entry_path_remove(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
int vrrp_vr_tracking_ifs_add_del(vrrp_vr_t *vr, vrrp_vr_tracking_if_t *track_ifs, u8 is_add)
static void vrrp_vr_skew_compute(vrrp_vr_t *vr)
static uword vnet_hw_interface_is_link_up(vnet_main_t *vnm, u32 hw_if_index)
int vrrp_vr_addr_add_del(vrrp_vr_t *vr, u8 is_add, ip46_address_t *vr_addr)
clib_error_t * vrrp_sw_interface_admin_up_down(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
bool ip6_link_delegate_update(u32 sw_if_index, ip6_link_delegate_id_t id, index_t ii)
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
static u32 vrrp_vr_lookup_address(u32 sw_if_index, u8 is_ipv6, void *addr)
#define VRRP6_MCAST_ADDR_AS_U8
void vrrp_vr_transition(vrrp_vr_t *vr, vrrp_vr_state_t new_state, void *data)
static uword pool_elts(void *v)
Number of active elements in a pool.