3 * vrrp.h - vrrp plug-in header file
5 * Copyright 2019-2020 Rubicon Communications, LLC (Netgate)
7 * SPDX-License-Identifier: Apache-2.0
10 #ifndef __included_vrrp_h__
11 #define __included_vrrp_h__
13 #include <vnet/vnet.h>
14 #include <vnet/ip/ip.h>
15 #include <vnet/ethernet/ethernet.h>
17 #include <vppinfra/hash.h>
18 #include <vppinfra/error.h>
20 /* VRRP configuration */
21 typedef enum vrrp_vr_flags
23 VRRP_VR_PREEMPT = 0x1,
25 VRRP_VR_UNICAST = 0x4,
29 typedef struct vrrp_vr_key
37 (struct vrrp4_arp_key {
48 (struct vrrp6_nd_key {
53 typedef struct vrrp_vr_tracking_if
57 } vrrp_vr_tracking_if_t;
59 typedef struct vrrp_vr_tracking
61 vrrp_vr_tracking_if_t *interfaces;
65 typedef struct vrrp_vr_config
71 vrrp_vr_flags_t flags;
72 ip46_address_t *vr_addrs;
73 ip46_address_t *peer_addrs;
76 #define foreach_vrrp_vr_state \
77 _(0, INIT, "Initialize") \
78 _(1, BACKUP, "Backup") \
79 _(2, MASTER, "Master") \
80 _(3, INTF_DOWN, "Interface Down")
82 /* VRRP runtime data */
83 typedef enum vrrp_vr_state
85 #define _(v,f,n) VRRP_VR_STATE_##f = v,
90 typedef struct vrrp_vr_runtime
92 vrrp_vr_state_t state;
102 typedef struct vrrp_vr
104 vrrp_vr_config_t config;
105 vrrp_vr_runtime_t runtime;
106 vrrp_vr_tracking_t tracking;
111 typedef enum vrrp_vr_timer_type
114 VRRP_VR_TIMER_MASTER_DOWN,
115 } vrrp_vr_timer_type_t;
117 typedef struct vrrp_vr_timer
120 f64 expire_time; /* monotonic, relative to vlib_time_now() */
121 vrrp_vr_timer_type_t type;
126 /* vectors of vr indices which are configured on this interface
127 * 0 -> ipv4, 1 -> ipv6 */
130 /* vector of VR indices which track the state of this interface
132 u32 *tracking_vrs[2];
134 /* multicast adjacency indices. 0 -> ipv4, 1 -> ipv6 */
135 adj_index_t mcast_adj_index[2];
137 /* number of VRs in master state on sw intf. 0 -> ipv4, 1 -> ipv6 */
144 /* API message ID base */
150 /* pool of timers and ordered vector of pool indices */
151 vrrp_vr_timer_t *vr_timers;
154 /* number of running VRs - don't register for VRRP proto if not running */
157 /* hash mapping a VR key to a pool entry */
158 mhash_t vr_index_by_key;
160 /* hashes mapping sw_if_index and address to a vr index */
161 uword *vrrp4_arp_lookup;
162 uword *vrrp6_nd_lookup;
164 /* vector of interface data indexed by sw_if_index */
165 vrrp_intf_t *vrrp_intfs;
168 vlib_main_t *vlib_main;
169 vnet_main_t *vnet_main;
170 ethernet_main_t *ethernet_main;
172 u32 intf_output_node_idx;
175 extern vrrp_main_t vrrp_main;
177 extern vlib_node_registration_t vrrp_node;
178 extern vlib_node_registration_t vrrp_periodic_node;
180 /* Periodic function events */
181 #define VRRP_EVENT_VR_TIMER_UPDATE 1
182 #define VRRP_EVENT_VR_STOP 2
183 #define VRRP_EVENT_PERIODIC_ENABLE_DISABLE 3
185 /* global error counter types */
186 #define foreach_vrrp_err_counter \
194 typedef enum vrrp_err_counter_
196 #define _(sym, val) VRRP_ERR_COUNTER_##sym = val,
197 foreach_vrrp_err_counter
199 } vrrp_err_counter_t;
201 #define VRRP_ERR_COUNTER_MAX 6
203 /* per-instance stats */
204 #define foreach_vrrp_stat_counter \
205 _ (MASTER_TRANS, 0) \
211 typedef enum vrrp_stat_counter_
213 #define _(sym, val) VRRP_STAT_COUNTER_##sym = val,
214 foreach_vrrp_stat_counter
216 } vrrp_stat_counter_t;
218 #define VRRP_STAT_COUNTER_MAX 5
220 clib_error_t *vrrp_plugin_api_hookup (vlib_main_t * vm);
222 int vrrp_vr_add_del (u8 is_add, vrrp_vr_config_t *conf, index_t *ret_index);
223 int vrrp_vr_update (index_t *vrrp_index, vrrp_vr_config_t *vr_conf);
224 int vrrp_vr_del (index_t vrrp_index);
225 int vrrp_vr_start_stop (u8 is_start, vrrp_vr_key_t * vr_key);
226 extern u8 *format_vrrp_vr (u8 * s, va_list * args);
227 extern u8 *format_vrrp_vr_key (u8 * s, va_list * args);
228 extern u8 *format_vrrp_vr_state (u8 * s, va_list * args);
229 extern u8 *format_vrrp_packet_hdr (u8 * s, va_list * args);
230 void vrrp_vr_timer_set (vrrp_vr_t * vr, vrrp_vr_timer_type_t type);
231 void vrrp_vr_timer_cancel (vrrp_vr_t * vr);
232 void vrrp_vr_transition (vrrp_vr_t * vr, vrrp_vr_state_t new_state,
234 int vrrp_vr_set_peers (vrrp_vr_key_t * key, ip46_address_t * peers);
235 int vrrp_vr_multicast_group_join (vrrp_vr_t * vr);
236 int vrrp_adv_send (vrrp_vr_t * vr, int shutdown);
237 int vrrp_garp_or_na_send (vrrp_vr_t * vr);
238 u16 vrrp_adv_csum (void *l3_hdr, void *payload, u8 is_ipv6, u16 len);
239 int vrrp_vr_tracking_if_add_del (vrrp_vr_t * vr, u32 sw_if_index,
240 u8 priority, u8 is_add);
241 int vrrp_vr_tracking_ifs_add_del (vrrp_vr_t * vr,
242 vrrp_vr_tracking_if_t * track_ifs,
244 void vrrp_vr_event (vrrp_vr_t * vr, vrrp_vr_state_t new_state);
247 void vrrp_incr_err_counter (vrrp_err_counter_t err_type);
248 void vrrp_incr_stat_counter (vrrp_stat_counter_t stat_type, u32 stat_index);
251 vrrp_vr_skew_compute (vrrp_vr_t * vr)
253 vrrp_vr_config_t *vrc = &vr->config;
254 vrrp_vr_runtime_t *vrt = &vr->runtime;
256 vrt->skew = (((256 - vrc->priority) * vrt->master_adv_int) / 256);
260 vrrp_vr_master_down_compute (vrrp_vr_t * vr)
262 vrrp_vr_runtime_t *vrt = &vr->runtime;
264 vrt->master_down_int = (3 * vrt->master_adv_int) + vrt->skew;
267 always_inline vrrp_vr_t *
268 vrrp_vr_lookup (u32 sw_if_index, u8 vr_id, u8 is_ipv6)
270 vrrp_main_t *vmp = &vrrp_main;
274 clib_memset (&key, 0, sizeof (key));
276 key.sw_if_index = sw_if_index;
278 key.is_ipv6 = (is_ipv6 != 0);
280 p = mhash_get (&vmp->vr_index_by_key, &key);
282 return pool_elt_at_index (vmp->vrs, p[0]);
287 always_inline vrrp_vr_t *
288 vrrp_vr_lookup_index (u32 vr_index)
290 vrrp_main_t *vmp = &vrrp_main;
292 if (pool_is_free_index (vmp->vrs, vr_index))
295 return pool_elt_at_index (vmp->vrs, vr_index);
299 vrrp_vr_lookup_address (u32 sw_if_index, u8 is_ipv6, void *addr)
301 vrrp_main_t *vmp = &vrrp_main;
303 vrrp4_arp_key_t key4;
308 key6.sw_if_index = sw_if_index;
309 key6.addr = ((ip6_address_t *) addr)[0];
310 p = hash_get_mem (vmp->vrrp6_nd_lookup, &key6);
314 key4.sw_if_index = sw_if_index;
315 key4.addr = ((ip4_address_t *) addr)[0];
316 p = hash_get (vmp->vrrp4_arp_lookup, key4.as_u64);
325 always_inline vrrp_intf_t *
326 vrrp_intf_get (u32 sw_if_index)
328 vrrp_main_t *vrm = &vrrp_main;
330 if (sw_if_index == ~0)
333 vec_validate (vrm->vrrp_intfs, sw_if_index);
334 return vec_elt_at_index (vrm->vrrp_intfs, sw_if_index);
338 vrrp_intf_num_vrs (u32 sw_if_index, u8 is_ipv6)
340 vrrp_intf_t *intf = vrrp_intf_get (sw_if_index);
343 return vec_len (intf->vr_indices[is_ipv6]);
349 vrrp_vr_is_ipv6 (vrrp_vr_t * vr)
351 return ((vr->config.flags & VRRP_VR_IPV6) != 0);
355 vrrp_vr_is_unicast (vrrp_vr_t * vr)
357 return ((vr->config.flags & VRRP_VR_UNICAST) != 0);
361 vrrp_vr_is_owner (vrrp_vr_t * vr)
363 return (vr->config.priority == 255);
367 vrrp_vr_n_vr_addrs (vrrp_vr_t * vr)
369 return vec_len (vr->config.vr_addrs);
373 vrrp_vr_n_peer_addrs (vrrp_vr_t * vr)
375 return vec_len (vr->config.peer_addrs);
379 vrrp_vr_accept_mode_enabled (vrrp_vr_t * vr)
381 return ((vr->config.flags & VRRP_VR_ACCEPT) != 0);
385 vrrp_vr_index (vrrp_vr_t * vr)
387 vrrp_main_t *vmp = &vrrp_main;
389 return vr - vmp->vrs;
393 vrrp_vr_priority (vrrp_vr_t * vr)
397 if (vr->tracking.interfaces_dec < (u32) vr->config.priority)
398 rv = vr->config.priority - vr->tracking.interfaces_dec;
405 #endif /* __included_vrrp_h__ */
408 * fd.io coding-style-patch-verification: ON
411 * eval: (c-set-style "gnu")