]>
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 | 25 | |
7c136b08 | 26 | #include "lib/memory.h" |
1d21789e QY |
27 | #include "lib/hash.h" |
28 | #include "lib/hook.h" | |
29 | #include "lib/if.h" | |
30 | #include "lib/linklist.h" | |
f495425b | 31 | #include "lib/northbound.h" |
1d21789e | 32 | #include "lib/privs.h" |
91188ca6 | 33 | #include "lib/stream.h" |
1d21789e | 34 | #include "lib/thread.h" |
f828842a | 35 | #include "lib/vty.h" |
5435a2bf QY |
36 | |
37 | /* Global definitions */ | |
f3fe0047 | 38 | #define VRRP_RADV_INT 16 |
5435a2bf | 39 | #define VRRP_PRIO_MASTER 255 |
862f2f37 QY |
40 | #define VRRP_MCASTV4_GROUP_STR "224.0.0.18" |
41 | #define VRRP_MCASTV6_GROUP_STR "ff02:0:0:0:0:0:0:12" | |
42 | #define VRRP_MCASTV4_GROUP 0xe0000012 | |
43 | #define VRRP_MCASTV6_GROUP 0xff020000000000000000000000000012 | |
5435a2bf QY |
44 | #define IPPROTO_VRRP 112 |
45 | ||
613b45b0 QY |
46 | #define VRRP_LOGPFX_VRID "[VRID %u] " |
47 | #define VRRP_LOGPFX_FAM "[%s] " | |
4ec94408 | 48 | |
8cd1d277 | 49 | /* Default defaults */ |
f495425b QY |
50 | #define VRRP_XPATH_FULL "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group" |
51 | #define VRRP_XPATH "./frr-vrrpd:vrrp/vrrp-group" | |
8cd1d277 QY |
52 | #define VRRP_DEFAULT_PRIORITY 100 |
53 | #define VRRP_DEFAULT_ADVINT 100 | |
54 | #define VRRP_DEFAULT_PREEMPT true | |
55 | #define VRRP_DEFAULT_ACCEPT true | |
56 | #define VRRP_DEFAULT_SHUTDOWN false | |
57 | ||
cb44d476 QY |
58 | /* User compatibility constant */ |
59 | #define CS2MS 10 | |
60 | ||
7c136b08 DL |
61 | DECLARE_MGROUP(VRRPD) |
62 | ||
f495425b QY |
63 | /* Northbound */ |
64 | extern const struct frr_yang_module_info frr_vrrpd_info; | |
65 | ||
8cd1d277 QY |
66 | /* Configured defaults */ |
67 | struct vrrp_defaults { | |
f495425b | 68 | uint8_t version; |
8cd1d277 QY |
69 | uint8_t priority; |
70 | uint16_t advertisement_interval; | |
71 | bool preempt_mode; | |
72 | bool accept_mode; | |
73 | bool shutdown; | |
74 | }; | |
75 | ||
76 | extern struct vrrp_defaults vd; | |
77 | ||
5435a2bf QY |
78 | /* threadmaster */ |
79 | extern struct thread_master *master; | |
80 | ||
b6029d6a QY |
81 | /* privileges */ |
82 | extern struct zebra_privs_t vrrp_privs; | |
83 | ||
5435a2bf | 84 | /* Global hash of all Virtual Routers */ |
27fd8827 | 85 | extern struct hash *vrrp_vrouters_hash; |
5435a2bf | 86 | |
27fd8827 QY |
87 | /* |
88 | * VRRP Router. | |
89 | * | |
90 | * This struct contains all state for a particular VRRP Router operating | |
91 | * in a Virtual Router for either IPv4 or IPv6. | |
92 | */ | |
93 | struct vrrp_router { | |
862f2f37 QY |
94 | /* |
95 | * Whether this VRRP Router is active. | |
96 | */ | |
97 | bool is_active; | |
98 | ||
10133a59 QY |
99 | /* Whether we are the address owner */ |
100 | bool is_owner; | |
101 | ||
dad18a2f QY |
102 | /* Rx socket: Rx from parent of mvl_ifp */ |
103 | int sock_rx; | |
104 | /* Tx socket; Tx from mvl_ifp */ | |
105 | int sock_tx; | |
106 | ||
107 | /* macvlan interface */ | |
108 | struct interface *mvl_ifp; | |
5435a2bf | 109 | |
8071d5c3 QY |
110 | /* Source address for advertisements */ |
111 | struct ipaddr src; | |
112 | ||
91188ca6 QY |
113 | /* Socket read buffer */ |
114 | uint8_t ibuf[IP_MAXPACKET]; | |
115 | ||
862f2f37 QY |
116 | /* |
117 | * Address family of this Virtual Router. | |
118 | * Either AF_INET or AF_INET6. | |
119 | */ | |
120 | int family; | |
5435a2bf QY |
121 | |
122 | /* | |
862f2f37 | 123 | * Virtual Router this VRRP Router is participating in. |
5435a2bf | 124 | */ |
862f2f37 | 125 | struct vrrp_vrouter *vr; |
5435a2bf | 126 | |
862f2f37 QY |
127 | /* |
128 | * One or more IPvX addresses associated with this Virtual | |
129 | * Router. The first address must be the "primary" address this | |
130 | * Virtual Router is backing up in the case of IPv4. In the case of | |
131 | * IPv6 it must be the link-local address of vr->ifp. | |
132 | * | |
133 | * Type: struct ipaddr * | |
134 | */ | |
135 | struct list *addrs; | |
5435a2bf | 136 | |
d60b2ffd QY |
137 | /* |
138 | * This flag says whether we are waiting on an interface up | |
139 | * notification from Zebra before we send an ADVERTISEMENT. | |
140 | */ | |
141 | bool advert_pending; | |
142 | ||
143 | /* | |
144 | * If this is an IPv4 VRRP router, this flag says whether we are | |
145 | * waiting on an interface up notification from Zebra before we send | |
146 | * gratuitous ARP packets for all our addresses. Should never be true | |
147 | * if family == AF_INET6. | |
148 | */ | |
149 | bool garp_pending; | |
150 | /* | |
151 | * If this is an IPv6 VRRP router, this flag says whether we are | |
152 | * waiting on an interface up notification from Zebra before we send | |
153 | * Unsolicited Neighbor Advertisement packets for all our addresses. | |
154 | * Should never be true if family == AF_INET. | |
155 | */ | |
156 | bool ndisc_pending; | |
157 | ||
5d3730c5 QY |
158 | /* |
159 | * Effective priority | |
862f2f37 | 160 | * => vr->priority if we are Backup |
5d3730c5 QY |
161 | * => 255 if we are Master |
162 | */ | |
5435a2bf QY |
163 | uint8_t priority; |
164 | ||
5435a2bf QY |
165 | /* |
166 | * Advertisement interval contained in ADVERTISEMENTS received from the | |
167 | * Master (centiseconds) | |
168 | */ | |
169 | uint16_t master_adver_interval; | |
170 | ||
171 | /* | |
172 | * Time to skew Master_Down_Interval in centiseconds. Calculated as: | |
173 | * (((256 - priority) * Master_Adver_Interval) / 256) | |
174 | */ | |
175 | uint16_t skew_time; | |
176 | ||
177 | /* | |
178 | * Time interval for Backup to declare Master down (centiseconds). | |
179 | * Calculated as: | |
180 | * (3 * Master_Adver_Interval) + Skew_time | |
181 | */ | |
182 | uint16_t master_down_interval; | |
183 | ||
862f2f37 QY |
184 | /* |
185 | * The MAC address used for the source MAC address in VRRP | |
186 | * advertisements, advertised in ARP requests/responses, and advertised | |
187 | * in ND Neighbor Advertisements. | |
188 | */ | |
189 | struct ethaddr vmac; | |
190 | ||
191 | struct { | |
192 | int state; | |
193 | } fsm; | |
194 | ||
6332c77f QY |
195 | struct { |
196 | /* Total number of advertisements sent and received */ | |
197 | uint32_t adver_tx_cnt; | |
198 | uint32_t adver_rx_cnt; | |
199 | /* Total number of gratuitous ARPs sent */ | |
200 | uint32_t garp_tx_cnt; | |
201 | /* Total number of unsolicited Neighbor Advertisements sent */ | |
202 | uint32_t una_tx_cnt; | |
203 | /* Total number of state transitions */ | |
204 | uint32_t trans_cnt; | |
205 | } stats; | |
206 | ||
862f2f37 QY |
207 | struct thread *t_master_down_timer; |
208 | struct thread *t_adver_timer; | |
91188ca6 QY |
209 | struct thread *t_read; |
210 | struct thread *t_write; | |
862f2f37 QY |
211 | }; |
212 | ||
213 | /* | |
214 | * VRRP Virtual Router. | |
215 | * | |
216 | * This struct contains all state and configuration for a given Virtual Router | |
217 | * Identifier on a given interface, both v4 and v6. | |
218 | * | |
219 | * RFC5798 s. 1 states: | |
220 | * "Within a VRRP router, the virtual routers in each of the IPv4 and IPv6 | |
221 | * address families are a domain unto themselves and do not overlap." | |
222 | * | |
223 | * This implementation has chosen the tuple (interface, VRID) as the key for a | |
224 | * particular VRRP Router, and the rest of the program is designed around this | |
225 | * assumption. Additionally, base protocol configuration parameters such as the | |
226 | * advertisement interval and (configured) priority are shared between v4 and | |
227 | * v6 instances. This corresponds to the choice made by other industrial | |
228 | * implementations. | |
229 | */ | |
230 | struct vrrp_vrouter { | |
53e60e5c QY |
231 | /* Whether this instance was automatically configured */ |
232 | bool autoconf; | |
233 | ||
6e93585e QY |
234 | /* Whether this VRRP router is in administrative shutdown */ |
235 | bool shutdown; | |
236 | ||
862f2f37 QY |
237 | /* Interface */ |
238 | struct interface *ifp; | |
239 | ||
91188ca6 QY |
240 | /* Version */ |
241 | uint8_t version; | |
242 | ||
862f2f37 QY |
243 | /* Virtual Router Identifier */ |
244 | uint32_t vrid; | |
245 | ||
246 | /* Configured priority */ | |
247 | uint8_t priority; | |
248 | ||
249 | /* | |
250 | * Time interval between ADVERTISEMENTS (centiseconds). Default is 100 | |
251 | * centiseconds (1 second). | |
252 | */ | |
253 | uint16_t advertisement_interval; | |
254 | ||
5435a2bf QY |
255 | /* |
256 | * Controls whether a (starting or restarting) higher-priority Backup | |
257 | * router preempts a lower-priority Master router. Values are True to | |
258 | * allow preemption and False to prohibit preemption. Default is True. | |
259 | */ | |
260 | bool preempt_mode; | |
261 | ||
262 | /* | |
263 | * Controls whether a virtual router in Master state will accept | |
264 | * packets addressed to the address owner's IPvX address as its own if | |
265 | * it is not the IPvX address owner. The default is False. | |
266 | */ | |
267 | bool accept_mode; | |
268 | ||
862f2f37 QY |
269 | struct vrrp_router *v4; |
270 | struct vrrp_router *v6; | |
5435a2bf QY |
271 | }; |
272 | ||
5435a2bf QY |
273 | /* |
274 | * Initialize VRRP global datastructures. | |
275 | */ | |
276 | void vrrp_init(void); | |
277 | ||
f1175ba9 QY |
278 | /* |
279 | * Destroy all VRRP instances and gracefully shutdown. | |
280 | * | |
281 | * For instances in Master state, VRRP advertisements with 0 priority will be | |
282 | * sent if possible to notify Backup routers that we are going away. | |
283 | */ | |
284 | void vrrp_fini(void); | |
285 | ||
1d21789e QY |
286 | |
287 | /* Creation and destruction ------------------------------------------------ */ | |
288 | ||
5435a2bf QY |
289 | /* |
290 | * Create and register a new VRRP Virtual Router. | |
1d21789e QY |
291 | * |
292 | * ifp | |
293 | * Base interface to configure VRRP on | |
294 | * | |
295 | * vrid | |
296 | * Virtual Router Identifier | |
5435a2bf | 297 | */ |
99966840 QY |
298 | struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid, |
299 | uint8_t version); | |
5435a2bf | 300 | |
c23edd74 | 301 | /* |
6287cefe QY |
302 | * Destroy a VRRP Virtual Router, freeing all its resources. |
303 | * | |
304 | * If there are any running VRRP instances, these are stopped and destroyed. | |
c23edd74 QY |
305 | */ |
306 | void vrrp_vrouter_destroy(struct vrrp_vrouter *vr); | |
307 | ||
1d21789e QY |
308 | |
309 | /* Configuration controllers ----------------------------------------------- */ | |
310 | ||
6e93585e QY |
311 | /* |
312 | * Check if a Virtual Router ought to be started, and if so, start it. | |
313 | * | |
314 | * vr | |
315 | * Virtual Router to checkstart | |
316 | */ | |
317 | void vrrp_check_start(struct vrrp_vrouter *vr); | |
318 | ||
c23edd74 | 319 | /* |
5d3730c5 | 320 | * Change the configured priority of a VRRP Virtual Router. |
c23edd74 | 321 | * |
5d3730c5 QY |
322 | * Note that this only changes the configured priority of the Virtual Router. |
323 | * The currently effective priority will not be changed; to change the | |
324 | * effective priority, the Virtual Router must be restarted by issuing a | |
325 | * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP. | |
c23edd74 | 326 | * |
1d21789e QY |
327 | * vr |
328 | * Virtual Router to change priority of | |
c23edd74 | 329 | * |
1d21789e QY |
330 | * priority |
331 | * New priority | |
c23edd74 | 332 | */ |
1d21789e | 333 | void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority); |
c23edd74 QY |
334 | |
335 | /* | |
1d21789e | 336 | * Set Advertisement Interval on this Virtual Router. |
c23edd74 QY |
337 | * |
338 | * vr | |
339 | * Virtual Router to change priority of | |
340 | * | |
1d21789e QY |
341 | * advertisement_interval |
342 | * New advertisement interval | |
c23edd74 | 343 | */ |
1d21789e QY |
344 | void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr, |
345 | uint16_t advertisement_interval); | |
c23edd74 QY |
346 | |
347 | /* | |
862f2f37 QY |
348 | * Add an IPvX address to a VRRP Virtual Router. |
349 | * | |
671fd2a3 | 350 | * vr |
862f2f37 QY |
351 | * Virtual Router to add IPvx address to |
352 | * | |
353 | * ip | |
354 | * Address to add | |
2cd90902 QY |
355 | * |
356 | * activate | |
357 | * Whether to automatically start the VRRP router if this is the first IP | |
358 | * address added. | |
359 | * | |
360 | * Returns: | |
361 | * -1 on error | |
362 | * 0 otherwise | |
862f2f37 | 363 | */ |
671fd2a3 | 364 | int vrrp_add_ip(struct vrrp_vrouter *vr, struct ipaddr *ip); |
862f2f37 QY |
365 | |
366 | /* | |
367 | * Add an IPv4 address to a VRRP Virtual Router. | |
c23edd74 QY |
368 | * |
369 | * vr | |
370 | * Virtual Router to add IPv4 address to | |
371 | * | |
372 | * v4 | |
373 | * Address to add | |
2cd90902 QY |
374 | * |
375 | * activate | |
376 | * Whether to automatically start the VRRP router if this is the first IP | |
377 | * address added. | |
378 | * | |
379 | * Returns: | |
380 | * -1 on error | |
381 | * 0 otherwise | |
c23edd74 | 382 | */ |
6e93585e | 383 | int vrrp_add_ipv4(struct vrrp_vrouter *vr, struct in_addr v4); |
862f2f37 QY |
384 | |
385 | /* | |
386 | * Add an IPv6 address to a VRRP Virtual Router. | |
387 | * | |
388 | * vr | |
389 | * Virtual Router to add IPv6 address to | |
390 | * | |
391 | * v6 | |
392 | * Address to add | |
2cd90902 QY |
393 | * |
394 | * activate | |
395 | * Whether to automatically start the VRRP router if this is the first IP | |
396 | * address added. | |
397 | * | |
398 | * Returns: | |
399 | * -1 on error | |
400 | * 0 otherwise | |
401 | */ | |
6e93585e | 402 | int vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6); |
2cd90902 QY |
403 | |
404 | /* | |
405 | * Remove an IP address from a VRRP Virtual Router. | |
406 | * | |
671fd2a3 | 407 | * vr |
2cd90902 QY |
408 | * Virtual Router to remove IP address from |
409 | * | |
410 | * ip | |
411 | * Address to remove | |
412 | * | |
413 | * deactivate | |
414 | * Whether to automatically stop the VRRP router if removing v4 would leave | |
415 | * us with an empty address list. If this is not true and ip is the only IP | |
416 | * address backed up by this virtual router, this function will not remove | |
417 | * the address and return failure. | |
418 | * | |
419 | * Returns: | |
420 | * -1 on error | |
421 | * 0 otherwise | |
422 | */ | |
671fd2a3 | 423 | int vrrp_del_ip(struct vrrp_vrouter *vr, struct ipaddr *ip); |
2cd90902 QY |
424 | |
425 | /* | |
426 | * Remove an IPv4 address from a VRRP Virtual Router. | |
427 | * | |
428 | * vr | |
429 | * Virtual Router to remove IPv4 address from | |
430 | * | |
431 | * v4 | |
432 | * Address to remove | |
433 | * | |
434 | * deactivate | |
435 | * Whether to automatically stop the VRRP router if removing v4 would leave | |
436 | * us with an empty address list. If this is not true and v4 is the only | |
437 | * IPv4 address backed up by this virtual router, this function will not | |
438 | * remove the address and return failure. | |
439 | * | |
440 | * Returns: | |
441 | * -1 on error | |
442 | * 0 otherwise | |
862f2f37 | 443 | */ |
6e93585e | 444 | int vrrp_del_ipv4(struct vrrp_vrouter *vr, struct in_addr v4); |
c23edd74 | 445 | |
2cd90902 QY |
446 | /* |
447 | * Remove an IPv6 address from a VRRP Virtual Router. | |
448 | * | |
449 | * vr | |
450 | * Virtual Router to remove IPv6 address from | |
451 | * | |
452 | * v6 | |
453 | * Address to remove | |
454 | * | |
455 | * deactivate | |
456 | * Whether to automatically stop the VRRP router if removing v5 would leave | |
457 | * us with an empty address list. If this is not true and v4 is the only | |
458 | * IPv6 address backed up by this virtual router, this function will not | |
459 | * remove the address and return failure. | |
460 | * | |
461 | * Returns: | |
462 | * -1 on error | |
463 | * 0 otherwise | |
464 | */ | |
6e93585e | 465 | int vrrp_del_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6); |
1d21789e QY |
466 | |
467 | /* State machine ----------------------------------------------------------- */ | |
468 | ||
4ec94408 QY |
469 | #define VRRP_STATE_INITIALIZE 0 |
470 | #define VRRP_STATE_MASTER 1 | |
471 | #define VRRP_STATE_BACKUP 2 | |
472 | #define VRRP_EVENT_STARTUP 0 | |
473 | #define VRRP_EVENT_SHUTDOWN 1 | |
474 | ||
2b64873d | 475 | extern const char *const vrrp_state_names[3]; |
1d21789e | 476 | |
5435a2bf | 477 | /* |
1d21789e QY |
478 | * This hook called whenever the state of a Virtual Router changes, after the |
479 | * specific internal state handlers have run. | |
480 | * | |
481 | * Use this if you need to react to state changes to perform non-critical | |
482 | * tasks. Critical tasks should go in the internal state change handlers. | |
5435a2bf | 483 | */ |
2fff50ec | 484 | DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_router *r, int to), (r, to)); |
5435a2bf QY |
485 | |
486 | /* | |
1d21789e QY |
487 | * Trigger a VRRP event on a given Virtual Router.. |
488 | * | |
489 | * vr | |
490 | * Virtual Router to operate on | |
491 | * | |
492 | * event | |
493 | * Event to kick off. All event related processing will have completed upon | |
494 | * return of this function. | |
495 | * | |
496 | * Returns: | |
497 | * < 0 if the event created an error | |
498 | * 0 otherwise | |
5435a2bf | 499 | */ |
862f2f37 | 500 | int vrrp_event(struct vrrp_router *r, int event); |
5435a2bf | 501 | |
27fd8827 | 502 | /* Autoconfig -------------------------------------------------------------- */ |
1d21789e | 503 | |
53e60e5c QY |
504 | /* |
505 | * Search for and automatically configure VRRP instances on interfaces. | |
506 | * | |
507 | * ifp | |
508 | * Interface to autoconfig. If it is a macvlan interface and has a VRRP MAC, | |
509 | * a VRRP instance corresponding to VMAC assigned to macvlan will be created | |
510 | * on the parent interface and all addresses on the macvlan interface except | |
511 | * the v6 link local will be configured as VRRP addresses. If NULL, this | |
512 | * treatment will be applied to all existing interfaces matching the above | |
513 | * criterion. | |
514 | * | |
515 | * Returns: | |
516 | * -1 on failure | |
517 | * 0 otherwise | |
518 | */ | |
27fd8827 QY |
519 | int vrrp_autoconfig(void); |
520 | ||
521 | /* | |
522 | * Enable autoconfiguration. | |
523 | * | |
524 | * Calling this function will cause vrrpd to automatically configure VRRP | |
525 | * instances on existing compatible macvlan interfaces. These instances will | |
526 | * react to interface up/down and address add/delete events to keep themselves | |
527 | * in sync with the available interfaces. | |
528 | * | |
529 | * version | |
530 | * VRRP version to use for autoconfigured instances. Must be 2 or 3. | |
531 | */ | |
532 | void vrrp_autoconfig_on(int version); | |
533 | ||
534 | /* | |
535 | * Disable autoconfiguration. | |
536 | * | |
537 | * Calling this function will delete all existing autoconfigured VRRP instances. | |
538 | */ | |
539 | void vrrp_autoconfig_off(void); | |
540 | ||
6e93585e | 541 | /* Interface Tracking ------------------------------------------------------ */ |
27fd8827 | 542 | |
6e93585e QY |
543 | void vrrp_if_add(struct interface *ifp); |
544 | void vrrp_if_del(struct interface *ifp); | |
545 | void vrrp_if_up(struct interface *ifp); | |
546 | void vrrp_if_down(struct interface *ifp); | |
547 | void vrrp_if_address_add(struct interface *ifp); | |
548 | void vrrp_if_address_del(struct interface *ifp); | |
27fd8827 QY |
549 | |
550 | /* Other ------------------------------------------------------------------- */ | |
53e60e5c | 551 | |
f828842a QY |
552 | /* |
553 | * Write global level configuration to vty. | |
554 | * | |
555 | * vty | |
556 | * vty to write config to | |
557 | * | |
558 | * Returns: | |
559 | * # of lines written | |
560 | */ | |
561 | int vrrp_config_write_global(struct vty *vty); | |
562 | ||
1d21789e QY |
563 | /* |
564 | * Find VRRP Virtual Router by Virtual Router ID | |
565 | */ | |
fb8b348c | 566 | struct vrrp_vrouter *vrrp_lookup(const struct interface *ifp, uint8_t vrid); |
1d21789e | 567 | |
63d4bd12 | 568 | #endif /* __VRRP_H__ */ |