FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
vrrp_periodic.c
Go to the documentation of this file.
1 /*
2  * vrrp_periodic.c - vrrp plug-in periodic function
3  *
4  * Copyright 2019-2020 Rubicon Communications, LLC (Netgate)
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  */
9 
10 #include <vlib/vlib.h>
11 #include <vppinfra/error.h>
12 #include <vrrp/vrrp.h>
13 #include <vrrp/vrrp_packet.h>
14 
15 static int
16 vrrp_vr_timer_compare (const void *v1, const void *v2)
17 {
18  vrrp_main_t *vmp = &vrrp_main;
19  const u32 *idx1, *idx2;
20  vrrp_vr_timer_t *timer1, *timer2;
21 
22  idx1 = v1;
23  idx2 = v2;
24 
25  timer1 = pool_elt_at_index (vmp->vr_timers, *idx1);
26  timer2 = pool_elt_at_index (vmp->vr_timers, *idx2);
27 
28  /* don't check equality, they are unlikely to be exactly equal and
29  * if it occurs, it won't matter what order they were in.
30  * sort the list in reverse so we can pick the next timer off the end */
31  if (timer1->expire_time > timer2->expire_time)
32  return -1;
33  else
34  return 1;
35 }
36 
37 static u32
39 {
40  vrrp_main_t *vmp = &vrrp_main;
41  int n_timers;
42 
43  n_timers = vec_len (vmp->pending_timers);
44 
45  if (!n_timers)
46  return ~0;
47 
48  return vec_elt (vmp->pending_timers, n_timers - 1);
49 }
50 
51 /* cancel an existing timer. This could happen because:
52  * - adv timer expired on master. another adv should be scheduled.
53  * - a shutdown event is received
54  * - a master is preempted by a higher priority master
55  * - adv received on backup. master down timer should be rescheduled.
56  */
57 void
59 {
60  vrrp_main_t *vmp = &vrrp_main;
61  u32 *t;
62 
63  /* don't search for a timer that was already canceled or never set */
64  if (vr->runtime.timer_index == ~0)
65  return;
66 
67  /* timers stored in descending order, start at the end of the list */
68  /* vec_foreach_backwards does not deal with 0 pointers, check first */
69  if (vmp->pending_timers)
71  {
72  if (*t == vr->runtime.timer_index)
73  {
74  vec_delete (vmp->pending_timers, 1, t - vmp->pending_timers);
75  break;
76  }
77  }
78 
81 
82  vr->runtime.timer_index = ~0;
83 
86 }
87 
88 void
90 {
91  vrrp_main_t *vmp = &vrrp_main;
93  vrrp_vr_timer_t *timer;
94  f64 now;
95 
96  /* Each VR should be waiting on at most 1 timer at any given time.
97  * If there is already a timer set for this VR, cancel it.
98  */
99  if (vr->runtime.timer_index != ~0)
101 
102  pool_get (vmp->vr_timers, timer);
103  vr->runtime.timer_index = timer - vmp->vr_timers;
104 
105  timer->vr_index = vr - vmp->vrs;
106  timer->type = type;
107 
108  now = vlib_time_now (vm);
109 
110  /* RFC 5798 specifies that timers are in centiseconds, so x / 100.0 */
111  switch (type)
112  {
113  case VRRP_VR_TIMER_ADV:
114  timer->expire_time = now + (vr->config.adv_interval / 100.0);
115  break;
117  timer->expire_time = now + (vr->runtime.master_down_int / 100.0);
118  break;
119  default:
120  /* should never reach here */
121  clib_warning ("Unrecognized VRRP timer type (%d)", type);
122  return;
123  }
124 
126 
128 
131 }
132 
133 void
135 {
136  vrrp_main_t *vmp = &vrrp_main;
137  vrrp_vr_timer_t *timer;
138  vrrp_vr_t *vr;
139 
140  if (pool_is_free_index (vmp->vr_timers, timer_index))
141  {
142  clib_warning ("Timeout on free timer index %u", timer_index);
143  return;
144  }
145 
146  timer = pool_elt_at_index (vmp->vr_timers, timer_index);
147  vr = pool_elt_at_index (vmp->vrs, timer->vr_index);
148 
149  switch (timer->type)
150  {
151  case VRRP_VR_TIMER_ADV:
152  vrrp_adv_send (vr, 0);
154  break;
156  vrrp_vr_transition (vr, VRRP_VR_STATE_MASTER, NULL);
157  break;
158  default:
159  clib_warning ("Unrecognized timer type %d", timer->type);
160  return;
161  }
162 
163 }
164 
165 static uword
168 {
169  vrrp_main_t *pm = &vrrp_main;
170  f64 now;
171  f64 timeout = 10.0;
172  uword *event_data = 0;
173  uword event_type;
174  u32 next_timer = ~0;
175  vrrp_vr_timer_t *timer;
176 
177  while (1)
178  {
179  now = vlib_time_now (vm);
180 
181  if (next_timer == ~0)
182  {
184  }
185  else
186  {
187  timer = pool_elt_at_index (pm->vr_timers, next_timer);
188  timeout = timer->expire_time - now;
189 
191  }
192 
193  event_type = vlib_process_get_events (vm, (uword **) & event_data);
194 
195  switch (event_type)
196  {
197  /* Handle VRRP_EVENT_VR_TIMER_UPDATE */
199  next_timer = vrrp_vr_timer_get_next ();
200  break;
201 
202  /* Handle periodic timeouts */
203  case ~0:
204  vrrp_vr_timer_timeout (next_timer);
205  next_timer = vrrp_vr_timer_get_next ();
206  break;
207  }
208  vec_reset_length (event_data);
209  }
210  return 0;
211 }
212 
213 /* *INDENT-OFF* */
215  .function = vrrp_periodic_process,
216  .type = VLIB_NODE_TYPE_PROCESS,
217  .name = "vrrp-periodic-process",
218  .process_log2_n_stack_bytes = 17,
219 };
220 /* *INDENT-ON* */
221 
222 /*
223  * fd.io coding-style-patch-verification: ON
224  *
225  * Local Variables:
226  * eval: (c-set-style "gnu")
227  * End:
228  */
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
vlib.h
vrrp_vr
Definition: vrrp.h:106
vrrp_vr::config
vrrp_vr_config_t config
Definition: vrrp.h:108
VRRP_EVENT_VR_TIMER_UPDATE
#define VRRP_EVENT_VR_TIMER_UPDATE
Definition: vrrp.h:184
vrrp_adv_send
int vrrp_adv_send(vrrp_vr_t *vr, int shutdown)
Definition: vrrp_packet.c:279
vrrp_periodic_node
vlib_node_registration_t vrrp_periodic_node
(constructor) VLIB_REGISTER_NODE (vrrp_periodic_node)
Definition: vrrp_periodic.c:214
vlib_process_wait_for_event
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:660
vrrp_vr_runtime::master_down_int
u16 master_down_int
Definition: vrrp.h:99
f
vlib_frame_t * f
Definition: interface_output.c:1098
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
vrrp_vr_timer_timeout
void vrrp_vr_timer_timeout(u32 timer_index)
Definition: vrrp_periodic.c:134
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vrrp_main_t::vr_timers
vrrp_vr_timer_t * vr_timers
Definition: vrrp.h:154
vec_delete
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:875
vrrp_vr::runtime
vrrp_vr_runtime_t runtime
Definition: vrrp.h:109
vrrp_vr_transition
void vrrp_vr_transition(vrrp_vr_t *vr, vrrp_vr_state_t new_state, void *data)
Definition: vrrp.c:282
vlib_frame_t
Definition: node.h:372
vlib_process_signal_event
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1019
pool_put_index
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
vrrp_vr_timer_set
void vrrp_vr_timer_set(vrrp_vr_t *vr, vrrp_vr_timer_type_t type)
Definition: vrrp_periodic.c:89
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
vrrp_vr_runtime::timer_index
u32 timer_index
Definition: vrrp.h:102
vlib_process_get_events
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
Definition: node_funcs.h:583
vrrp_vr_timer::expire_time
f64 expire_time
Definition: vrrp.h:123
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
error.h
vrrp_packet.h
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vrrp_vr_timer
Definition: vrrp.h:120
vrrp.h
uword
u64 uword
Definition: types.h:112
vrrp_periodic_process
static uword vrrp_periodic_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: vrrp_periodic.c:166
vrrp_vr_timer_cancel
void vrrp_vr_timer_cancel(vrrp_vr_t *vr)
Definition: vrrp_periodic.c:58
vrrp_vr_timer_type_t
enum vrrp_vr_timer_type vrrp_vr_timer_type_t
f64
double f64
Definition: types.h:142
vrrp_vr_timer_compare
static int vrrp_vr_timer_compare(const void *v1, const void *v2)
Definition: vrrp_periodic.c:16
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
vrrp_main_t
Definition: vrrp.h:145
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vrrp_vr_timer::vr_index
u32 vr_index
Definition: vrrp.h:122
vlib_process_wait_for_event_or_clock
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:755
u32
unsigned int u32
Definition: types.h:88
vrrp_main_t::pending_timers
u32 * pending_timers
Definition: vrrp.h:155
vrrp_vr_config::adv_interval
u16 adv_interval
Definition: vrrp.h:74
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
vrrp_main_t::vlib_main
vlib_main_t * vlib_main
Definition: vrrp.h:171
now
f64 now
Definition: nat44_ei_out2in.c:710
vec_sort_with_function
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1097
vlib_main_t
Definition: main.h:102
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:419
VRRP_VR_TIMER_MASTER_DOWN
@ VRRP_VR_TIMER_MASTER_DOWN
Definition: vrrp.h:117
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
vrrp_main_t::vrs
vrrp_vr_t * vrs
Definition: vrrp.h:151
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
vlib_node_runtime_t
Definition: node.h:454
vrrp_vr_timer::type
vrrp_vr_timer_type_t type
Definition: vrrp.h:124
vrrp_main
vrrp_main_t vrrp_main
Definition: vrrp.c:25
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
VRRP_VR_TIMER_ADV
@ VRRP_VR_TIMER_ADV
Definition: vrrp.h:116
vrrp_vr_timer_get_next
static u32 vrrp_vr_timer_get_next(void)
Definition: vrrp_periodic.c:38
vec_foreach_backwards
#define vec_foreach_backwards(var, vec)
Vector iterator (reverse)
Definition: vec_bootstrap.h:216
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169