]>
Commit | Line | Data |
---|---|---|
5435a2bf | 1 | /* |
63d4bd12 QY |
2 | * VRRP global definitions and state machine. |
3 | * Copyright (C) 2018-2019 Cumulus Networks, Inc. | |
4 | * Quentin Young | |
5435a2bf QY |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the Free | |
8 | * Software Foundation; either version 2 of the License, or (at your option) | |
9 | * any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
14 | * more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
63d4bd12 QY |
20 | #ifndef __VRRP_H__ |
21 | #define __VRRP_H__ | |
5435a2bf QY |
22 | |
23 | #include <zebra.h> | |
91188ca6 | 24 | #include <netinet/ip.h> |
1d21789e QY |
25 | |
26 | #include "lib/hash.h" | |
27 | #include "lib/hook.h" | |
28 | #include "lib/if.h" | |
29 | #include "lib/linklist.h" | |
30 | #include "lib/privs.h" | |
91188ca6 | 31 | #include "lib/stream.h" |
1d21789e | 32 | #include "lib/thread.h" |
5435a2bf QY |
33 | |
34 | /* Global definitions */ | |
35 | #define VRRP_DEFAULT_ADVINT 100 | |
36 | #define VRRP_DEFAULT_PRIORITY 100 | |
f3fe0047 | 37 | #define VRRP_RADV_INT 16 |
5435a2bf | 38 | #define VRRP_PRIO_MASTER 255 |
862f2f37 QY |
39 | #define VRRP_MCASTV4_GROUP_STR "224.0.0.18" |
40 | #define VRRP_MCASTV6_GROUP_STR "ff02:0:0:0:0:0:0:12" | |
41 | #define VRRP_MCASTV4_GROUP 0xe0000012 | |
42 | #define VRRP_MCASTV6_GROUP 0xff020000000000000000000000000012 | |
5435a2bf QY |
43 | #define IPPROTO_VRRP 112 |
44 | ||
4ec94408 QY |
45 | #define VRRP_LOGPFX_VRID "[VRID: %u] " |
46 | ||
5435a2bf QY |
47 | /* threadmaster */ |
48 | extern struct thread_master *master; | |
49 | ||
b6029d6a QY |
50 | /* privileges */ |
51 | extern struct zebra_privs_t vrrp_privs; | |
52 | ||
5435a2bf QY |
53 | /* Global hash of all Virtual Routers */ |
54 | struct hash *vrrp_vrouters_hash; | |
55 | ||
56 | /* | |
862f2f37 QY |
57 | * VRRP Router. |
58 | * | |
59 | * This struct contains all state for a particular VRRP Router operating in a | |
60 | * Virtual Router for either IPv4 or IPv6. | |
5435a2bf | 61 | */ |
862f2f37 QY |
62 | struct vrrp_router { |
63 | /* | |
64 | * Whether this VRRP Router is active. | |
65 | */ | |
66 | bool is_active; | |
67 | ||
10133a59 QY |
68 | /* Whether we are the address owner */ |
69 | bool is_owner; | |
70 | ||
dad18a2f QY |
71 | /* Rx socket: Rx from parent of mvl_ifp */ |
72 | int sock_rx; | |
73 | /* Tx socket; Tx from mvl_ifp */ | |
74 | int sock_tx; | |
75 | ||
76 | /* macvlan interface */ | |
77 | struct interface *mvl_ifp; | |
5435a2bf | 78 | |
8071d5c3 QY |
79 | /* Source address for advertisements */ |
80 | struct ipaddr src; | |
81 | ||
91188ca6 QY |
82 | /* Socket read buffer */ |
83 | uint8_t ibuf[IP_MAXPACKET]; | |
84 | ||
862f2f37 QY |
85 | /* |
86 | * Address family of this Virtual Router. | |
87 | * Either AF_INET or AF_INET6. | |
88 | */ | |
89 | int family; | |
5435a2bf QY |
90 | |
91 | /* | |
862f2f37 | 92 | * Virtual Router this VRRP Router is participating in. |
5435a2bf | 93 | */ |
862f2f37 | 94 | struct vrrp_vrouter *vr; |
5435a2bf | 95 | |
862f2f37 QY |
96 | /* |
97 | * One or more IPvX addresses associated with this Virtual | |
98 | * Router. The first address must be the "primary" address this | |
99 | * Virtual Router is backing up in the case of IPv4. In the case of | |
100 | * IPv6 it must be the link-local address of vr->ifp. | |
101 | * | |
102 | * Type: struct ipaddr * | |
103 | */ | |
104 | struct list *addrs; | |
5435a2bf | 105 | |
5d3730c5 QY |
106 | /* |
107 | * Effective priority | |
862f2f37 | 108 | * => vr->priority if we are Backup |
5d3730c5 QY |
109 | * => 255 if we are Master |
110 | */ | |
5435a2bf QY |
111 | uint8_t priority; |
112 | ||
5435a2bf QY |
113 | /* |
114 | * Advertisement interval contained in ADVERTISEMENTS received from the | |
115 | * Master (centiseconds) | |
116 | */ | |
117 | uint16_t master_adver_interval; | |
118 | ||
119 | /* | |
120 | * Time to skew Master_Down_Interval in centiseconds. Calculated as: | |
121 | * (((256 - priority) * Master_Adver_Interval) / 256) | |
122 | */ | |
123 | uint16_t skew_time; | |
124 | ||
125 | /* | |
126 | * Time interval for Backup to declare Master down (centiseconds). | |
127 | * Calculated as: | |
128 | * (3 * Master_Adver_Interval) + Skew_time | |
129 | */ | |
130 | uint16_t master_down_interval; | |
131 | ||
862f2f37 QY |
132 | /* |
133 | * The MAC address used for the source MAC address in VRRP | |
134 | * advertisements, advertised in ARP requests/responses, and advertised | |
135 | * in ND Neighbor Advertisements. | |
136 | */ | |
137 | struct ethaddr vmac; | |
138 | ||
139 | struct { | |
140 | int state; | |
141 | } fsm; | |
142 | ||
143 | struct thread *t_master_down_timer; | |
144 | struct thread *t_adver_timer; | |
91188ca6 QY |
145 | struct thread *t_read; |
146 | struct thread *t_write; | |
862f2f37 QY |
147 | }; |
148 | ||
149 | /* | |
150 | * VRRP Virtual Router. | |
151 | * | |
152 | * This struct contains all state and configuration for a given Virtual Router | |
153 | * Identifier on a given interface, both v4 and v6. | |
154 | * | |
155 | * RFC5798 s. 1 states: | |
156 | * "Within a VRRP router, the virtual routers in each of the IPv4 and IPv6 | |
157 | * address families are a domain unto themselves and do not overlap." | |
158 | * | |
159 | * This implementation has chosen the tuple (interface, VRID) as the key for a | |
160 | * particular VRRP Router, and the rest of the program is designed around this | |
161 | * assumption. Additionally, base protocol configuration parameters such as the | |
162 | * advertisement interval and (configured) priority are shared between v4 and | |
163 | * v6 instances. This corresponds to the choice made by other industrial | |
164 | * implementations. | |
165 | */ | |
166 | struct vrrp_vrouter { | |
167 | /* Interface */ | |
168 | struct interface *ifp; | |
169 | ||
91188ca6 QY |
170 | /* Version */ |
171 | uint8_t version; | |
172 | ||
862f2f37 QY |
173 | /* Virtual Router Identifier */ |
174 | uint32_t vrid; | |
175 | ||
176 | /* Configured priority */ | |
177 | uint8_t priority; | |
178 | ||
179 | /* | |
180 | * Time interval between ADVERTISEMENTS (centiseconds). Default is 100 | |
181 | * centiseconds (1 second). | |
182 | */ | |
183 | uint16_t advertisement_interval; | |
184 | ||
5435a2bf QY |
185 | /* |
186 | * Controls whether a (starting or restarting) higher-priority Backup | |
187 | * router preempts a lower-priority Master router. Values are True to | |
188 | * allow preemption and False to prohibit preemption. Default is True. | |
189 | */ | |
190 | bool preempt_mode; | |
191 | ||
192 | /* | |
193 | * Controls whether a virtual router in Master state will accept | |
194 | * packets addressed to the address owner's IPvX address as its own if | |
195 | * it is not the IPvX address owner. The default is False. | |
196 | */ | |
197 | bool accept_mode; | |
198 | ||
862f2f37 QY |
199 | struct vrrp_router *v4; |
200 | struct vrrp_router *v6; | |
5435a2bf QY |
201 | }; |
202 | ||
5435a2bf QY |
203 | /* |
204 | * Initialize VRRP global datastructures. | |
205 | */ | |
206 | void vrrp_init(void); | |
207 | ||
1d21789e QY |
208 | |
209 | /* Creation and destruction ------------------------------------------------ */ | |
210 | ||
5435a2bf QY |
211 | /* |
212 | * Create and register a new VRRP Virtual Router. | |
1d21789e QY |
213 | * |
214 | * ifp | |
215 | * Base interface to configure VRRP on | |
216 | * | |
217 | * vrid | |
218 | * Virtual Router Identifier | |
5435a2bf QY |
219 | */ |
220 | struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid); | |
221 | ||
c23edd74 | 222 | /* |
6287cefe QY |
223 | * Destroy a VRRP Virtual Router, freeing all its resources. |
224 | * | |
225 | * If there are any running VRRP instances, these are stopped and destroyed. | |
c23edd74 QY |
226 | */ |
227 | void vrrp_vrouter_destroy(struct vrrp_vrouter *vr); | |
228 | ||
1d21789e QY |
229 | |
230 | /* Configuration controllers ----------------------------------------------- */ | |
231 | ||
c23edd74 | 232 | /* |
5d3730c5 | 233 | * Change the configured priority of a VRRP Virtual Router. |
c23edd74 | 234 | * |
5d3730c5 QY |
235 | * Note that this only changes the configured priority of the Virtual Router. |
236 | * The currently effective priority will not be changed; to change the | |
237 | * effective priority, the Virtual Router must be restarted by issuing a | |
238 | * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP. | |
c23edd74 | 239 | * |
1d21789e QY |
240 | * vr |
241 | * Virtual Router to change priority of | |
c23edd74 | 242 | * |
1d21789e QY |
243 | * priority |
244 | * New priority | |
c23edd74 | 245 | */ |
1d21789e | 246 | void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority); |
c23edd74 QY |
247 | |
248 | /* | |
1d21789e | 249 | * Set Advertisement Interval on this Virtual Router. |
c23edd74 QY |
250 | * |
251 | * vr | |
252 | * Virtual Router to change priority of | |
253 | * | |
1d21789e QY |
254 | * advertisement_interval |
255 | * New advertisement interval | |
c23edd74 | 256 | */ |
1d21789e QY |
257 | void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr, |
258 | uint16_t advertisement_interval); | |
c23edd74 QY |
259 | |
260 | /* | |
862f2f37 QY |
261 | * Add an IPvX address to a VRRP Virtual Router. |
262 | * | |
2cd90902 | 263 | * r |
862f2f37 QY |
264 | * Virtual Router to add IPvx address to |
265 | * | |
266 | * ip | |
267 | * Address to add | |
2cd90902 QY |
268 | * |
269 | * activate | |
270 | * Whether to automatically start the VRRP router if this is the first IP | |
271 | * address added. | |
272 | * | |
273 | * Returns: | |
274 | * -1 on error | |
275 | * 0 otherwise | |
862f2f37 | 276 | */ |
2cd90902 | 277 | int vrrp_add_ip(struct vrrp_router *r, struct ipaddr *ip, bool activate); |
862f2f37 QY |
278 | |
279 | /* | |
280 | * Add an IPv4 address to a VRRP Virtual Router. | |
c23edd74 QY |
281 | * |
282 | * vr | |
283 | * Virtual Router to add IPv4 address to | |
284 | * | |
285 | * v4 | |
286 | * Address to add | |
2cd90902 QY |
287 | * |
288 | * activate | |
289 | * Whether to automatically start the VRRP router if this is the first IP | |
290 | * address added. | |
291 | * | |
292 | * Returns: | |
293 | * -1 on error | |
294 | * 0 otherwise | |
c23edd74 | 295 | */ |
2cd90902 | 296 | int vrrp_add_ipv4(struct vrrp_vrouter *vr, struct in_addr v4, bool activate); |
862f2f37 QY |
297 | |
298 | /* | |
299 | * Add an IPv6 address to a VRRP Virtual Router. | |
300 | * | |
301 | * vr | |
302 | * Virtual Router to add IPv6 address to | |
303 | * | |
304 | * v6 | |
305 | * Address to add | |
2cd90902 QY |
306 | * |
307 | * activate | |
308 | * Whether to automatically start the VRRP router if this is the first IP | |
309 | * address added. | |
310 | * | |
311 | * Returns: | |
312 | * -1 on error | |
313 | * 0 otherwise | |
314 | */ | |
315 | int vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6, bool activate); | |
316 | ||
317 | /* | |
318 | * Remove an IP address from a VRRP Virtual Router. | |
319 | * | |
320 | * r | |
321 | * Virtual Router to remove IP address from | |
322 | * | |
323 | * ip | |
324 | * Address to remove | |
325 | * | |
326 | * deactivate | |
327 | * Whether to automatically stop the VRRP router if removing v4 would leave | |
328 | * us with an empty address list. If this is not true and ip is the only IP | |
329 | * address backed up by this virtual router, this function will not remove | |
330 | * the address and return failure. | |
331 | * | |
332 | * Returns: | |
333 | * -1 on error | |
334 | * 0 otherwise | |
335 | */ | |
336 | int vrrp_del_ip(struct vrrp_router *r, struct ipaddr *ip, bool deactivate); | |
337 | ||
338 | /* | |
339 | * Remove an IPv4 address from a VRRP Virtual Router. | |
340 | * | |
341 | * vr | |
342 | * Virtual Router to remove IPv4 address from | |
343 | * | |
344 | * v4 | |
345 | * Address to remove | |
346 | * | |
347 | * deactivate | |
348 | * Whether to automatically stop the VRRP router if removing v4 would leave | |
349 | * us with an empty address list. If this is not true and v4 is the only | |
350 | * IPv4 address backed up by this virtual router, this function will not | |
351 | * remove the address and return failure. | |
352 | * | |
353 | * Returns: | |
354 | * -1 on error | |
355 | * 0 otherwise | |
862f2f37 | 356 | */ |
2cd90902 | 357 | int vrrp_del_ipv4(struct vrrp_vrouter *vr, struct in_addr v4, bool deactivate); |
c23edd74 | 358 | |
2cd90902 QY |
359 | /* |
360 | * Remove an IPv6 address from a VRRP Virtual Router. | |
361 | * | |
362 | * vr | |
363 | * Virtual Router to remove IPv6 address from | |
364 | * | |
365 | * v6 | |
366 | * Address to remove | |
367 | * | |
368 | * deactivate | |
369 | * Whether to automatically stop the VRRP router if removing v5 would leave | |
370 | * us with an empty address list. If this is not true and v4 is the only | |
371 | * IPv6 address backed up by this virtual router, this function will not | |
372 | * remove the address and return failure. | |
373 | * | |
374 | * Returns: | |
375 | * -1 on error | |
376 | * 0 otherwise | |
377 | */ | |
378 | int vrrp_del_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6, bool deactivate); | |
1d21789e QY |
379 | |
380 | /* State machine ----------------------------------------------------------- */ | |
381 | ||
4ec94408 QY |
382 | #define VRRP_STATE_INITIALIZE 0 |
383 | #define VRRP_STATE_MASTER 1 | |
384 | #define VRRP_STATE_BACKUP 2 | |
385 | #define VRRP_EVENT_STARTUP 0 | |
386 | #define VRRP_EVENT_SHUTDOWN 1 | |
387 | ||
388 | extern const char *vrrp_state_names[3]; | |
389 | extern const char *vrrp_event_names[2]; | |
1d21789e | 390 | |
5435a2bf | 391 | /* |
1d21789e QY |
392 | * This hook called whenever the state of a Virtual Router changes, after the |
393 | * specific internal state handlers have run. | |
394 | * | |
395 | * Use this if you need to react to state changes to perform non-critical | |
396 | * tasks. Critical tasks should go in the internal state change handlers. | |
5435a2bf | 397 | */ |
862f2f37 | 398 | DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_router * r, int to), (r, to)); |
5435a2bf QY |
399 | |
400 | /* | |
1d21789e QY |
401 | * Trigger a VRRP event on a given Virtual Router.. |
402 | * | |
403 | * vr | |
404 | * Virtual Router to operate on | |
405 | * | |
406 | * event | |
407 | * Event to kick off. All event related processing will have completed upon | |
408 | * return of this function. | |
409 | * | |
410 | * Returns: | |
411 | * < 0 if the event created an error | |
412 | * 0 otherwise | |
5435a2bf | 413 | */ |
862f2f37 | 414 | int vrrp_event(struct vrrp_router *r, int event); |
5435a2bf | 415 | |
1d21789e QY |
416 | |
417 | /* Other ------------------------------------------------------------------- */ | |
418 | ||
419 | /* | |
420 | * Find VRRP Virtual Router by Virtual Router ID | |
421 | */ | |
4f0b6b45 | 422 | struct vrrp_vrouter *vrrp_lookup(struct interface *ifp, uint8_t vrid); |
1d21789e | 423 | |
63d4bd12 | 424 | #endif /* __VRRP_H__ */ |