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;
143 const char *mc_arc_name = 0, *mc_node_name = 0;
146 int n_master_accept = 0;
151 arc_name =
"ip6-local";
152 node_name =
"vrrp6-nd-input";
153 mc_arc_name =
"ip6-multicast";
154 mc_node_name =
"vrrp6-accept-owner-input";
159 node_name =
"vrrp4-arp-input";
160 mc_arc_name =
"ip4-multicast";
161 mc_node_name =
"vrrp4-accept-owner-input";
188 (new_state == VRRP_VR_STATE_INIT)) && (n_started == 0))
191 (new_state != VRRP_VR_STATE_INIT), NULL, 0);
195 (new_state == VRRP_VR_STATE_MASTER))
198 if (new_state == VRRP_VR_STATE_MASTER)
210 (new_state == VRRP_VR_STATE_MASTER),
221 ip46_address_t *vr_addr;
235 (new_state != VRRP_VR_STATE_MASTER))
238 is_del = (new_state != VRRP_VR_STATE_MASTER);
267 ip6_address_t *intf6;
294 if (new_state == VRRP_VR_STATE_MASTER)
306 else if (new_state == VRRP_VR_STATE_BACKUP)
316 vrrp_header_t *pkt =
data;
328 else if (new_state == VRRP_VR_STATE_INIT)
338 else if (new_state == VRRP_VR_STATE_INTF_DOWN)
359 #define VRRP4_MCAST_ADDR_AS_U8 { 224, 0, 0, 18 } 360 #define VRRP6_MCAST_ADDR_AS_U8 \ 361 { 0xff, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12 } 480 if (per_intf_index != ~0)
499 ip46_address_t *
addr;
505 return VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
514 ip46_address_t *vr_addr;
522 addr = (
is_ipv6) ? (
void *) &vr_addr->ip6 : (
void *) &vr_addr->ip4;
525 return VNET_API_ERROR_ADDRESS_IN_USE;
552 vrrp4_arp_key_t key4;
554 ip46_address_t *
addr;
557 return VNET_API_ERROR_INVALID_ARGUMENT;
559 vr_index = vr - vmp->
vrs;
564 key6.addr = vr_addr->ip6;
586 key4.addr = vr_addr->ip4;
612 ip46_address_t *vr_addr;
634 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
649 clib_warning (
"VR %u for IPv%d already exists on sw_if_index %u",
651 return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
657 clib_warning (
"Conf of VR %u for IPv%d on sw_if_index %u " 658 " does not contain IP addresses",
660 return VNET_API_ERROR_INVALID_SRC_ADDRESS;
668 vr_index = vr - vrm->
vrs;
688 clib_warning (
"No VR %u for IPv%d exists on sw_if_index %u",
690 return VNET_API_ERROR_NO_SUCH_ENTRY;
718 return VNET_API_ERROR_NO_SUCH_ENTRY;
725 case VRRP_VR_STATE_INIT:
728 clib_warning (
"Attempting to stop already stopped VR (%U)",
736 clib_warning (
"Attempting to start already started VR (%U)",
748 return VNET_API_ERROR_INIT_FAILED;
784 return VNET_API_ERROR_INVALID_ARGUMENT;
790 return VNET_API_ERROR_RSRC_IN_USE;
796 return VNET_API_ERROR_INVALID_DST_ADDRESS;
812 return VNET_API_ERROR_NO_SUCH_ENTRY;
915 int admin_up, link_up, ip_up;
921 return (admin_up && link_up && ip_up);
934 u32 total_priority = 0;
946 clib_warning (
"VR %U interface track adjustment change from %u to %u",
963 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
967 return VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
1006 ifs_copy =
vec_dup (track_ifs);
1012 track_if->
priority, (is_add != 0));
1019 for (rb_if = track_if - 1; rb_if >= track_ifs; rb_if -= 1)
1074 for (i = 0; i < 2; i++)
1095 vr_state = VRRP_VR_STATE_INTF_DOWN;
1102 VRRP_VR_STATE_MASTER : VRRP_VR_STATE_BACKUP;
1151 .hw_if_index = hw_if_index,
1170 u32 if_address_index,
u32 is_del)
1181 u32 indent = va_arg (*args,
u32);
1187 s =
format (s,
"%UVRRP VRs monitoring this link:\n",
1278 .version = VPP_BUILD_VER,
1279 .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)
vl_api_wireguard_peer_flags_t flags
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]
#define pool_foreach(VAR, POOL)
Iterate through pool.
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)
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.
#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)
description fragment has unexpected format
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)
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 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)
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.
#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)
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
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)
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.
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
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
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)
void vrrp_vr_event(vrrp_vr_t *vr, vrrp_vr_state_t new_state)
vl_api_interface_index_t sw_if_index
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.